mirror of
https://github.com/apache/rocketmq.git
synced 2026-09-21 05:44:03 +08:00
* [RIP-26] Both CQ and BCQ will be supported in DefaultMessageStore. * [RIP-26] Both CQ and BCQ will be supported in DefaultMessageStore.
This commit is contained in:
committed by
RongtongJin
parent
5ce1b88cf0
commit
e8cf133874
@@ -96,11 +96,9 @@ import org.apache.rocketmq.srvutil.FileWatchService;
|
||||
import org.apache.rocketmq.store.DefaultMessageStore;
|
||||
import org.apache.rocketmq.store.MessageArrivingListener;
|
||||
import org.apache.rocketmq.store.MessageStore;
|
||||
import org.apache.rocketmq.store.StreamMessageStore;
|
||||
import org.apache.rocketmq.store.config.BrokerRole;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
import org.apache.rocketmq.store.dledger.DLedgerCommitLog;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
import org.apache.rocketmq.store.stats.BrokerStats;
|
||||
import org.apache.rocketmq.store.stats.BrokerStatsManager;
|
||||
|
||||
@@ -298,14 +296,9 @@ public class BrokerController {
|
||||
|
||||
if (result) {
|
||||
try {
|
||||
MessageStore messageStore;
|
||||
if (Objects.equals(CQType.BatchCQ.toString(), this.messageStoreConfig.getDefaultCQType())) {
|
||||
messageStore = new StreamMessageStore(this.messageStoreConfig, this.brokerStatsManager, this.messageArrivingListener, this.brokerConfig);
|
||||
} else {
|
||||
messageStore = new DefaultMessageStore(this.messageStoreConfig, this.brokerStatsManager, this.messageArrivingListener, this.brokerConfig);
|
||||
}
|
||||
this.messageStore = new DefaultMessageStore(this.messageStoreConfig, this.brokerStatsManager, this.messageArrivingListener, this.brokerConfig);
|
||||
((DefaultMessageStore) this.messageStore).setTopicConfigTable(topicConfigManager.getTopicConfigTable());
|
||||
|
||||
this.messageStore = messageStore;
|
||||
if (messageStoreConfig.isEnableDLegerCommitLog()) {
|
||||
DLedgerRoleChangeHandler roleChangeHandler = new DLedgerRoleChangeHandler(this, (DefaultMessageStore) messageStore);
|
||||
((DLedgerCommitLog) messageStore.getCommitLog()).getdLedgerServer().getdLedgerLeaderElector().addRoleChangeHandler(roleChangeHandler);
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.apache.rocketmq.common.BrokerConfig;
|
||||
import org.apache.rocketmq.common.MQVersion;
|
||||
import org.apache.rocketmq.common.MixAll;
|
||||
import org.apache.rocketmq.common.PlainAccessConfig;
|
||||
import org.apache.rocketmq.common.TopicAttributes;
|
||||
import org.apache.rocketmq.common.TopicConfig;
|
||||
import org.apache.rocketmq.common.UtilAll;
|
||||
import org.apache.rocketmq.common.admin.ConsumeStats;
|
||||
|
||||
@@ -32,12 +32,10 @@ import org.apache.rocketmq.common.protocol.header.UpdateConsumerOffsetResponseHe
|
||||
import org.apache.rocketmq.common.rpc.RpcClientUtils;
|
||||
import org.apache.rocketmq.common.rpc.RpcRequest;
|
||||
import org.apache.rocketmq.common.rpc.RpcResponse;
|
||||
import org.apache.rocketmq.common.rpc.TopicQueueRequestHeader;
|
||||
import org.apache.rocketmq.common.statictopic.LogicQueueMappingItem;
|
||||
import org.apache.rocketmq.common.statictopic.TopicQueueMappingContext;
|
||||
import org.apache.rocketmq.common.statictopic.TopicQueueMappingDetail;
|
||||
import org.apache.rocketmq.common.statictopic.TopicQueueMappingUtils;
|
||||
import org.apache.rocketmq.common.sysflag.PullSysFlag;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.remoting.common.RemotingHelper;
|
||||
|
||||
@@ -18,9 +18,9 @@ package org.apache.rocketmq.broker.processor;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
@@ -42,7 +42,6 @@ import org.apache.rocketmq.common.constant.PermName;
|
||||
import org.apache.rocketmq.common.help.FAQUrl;
|
||||
import org.apache.rocketmq.common.message.MessageAccessor;
|
||||
import org.apache.rocketmq.common.message.MessageClientIDSetter;
|
||||
import org.apache.rocketmq.common.message.MessageClientIDSetter;
|
||||
import org.apache.rocketmq.common.message.MessageConst;
|
||||
import org.apache.rocketmq.common.message.MessageDecoder;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
@@ -56,6 +55,7 @@ import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
|
||||
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
|
||||
import org.apache.rocketmq.common.sysflag.TopicSysFlag;
|
||||
import org.apache.rocketmq.common.topic.TopicValidator;
|
||||
import org.apache.rocketmq.common.utils.QueueTypeUtils;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
|
||||
import org.apache.rocketmq.remoting.netty.NettyRequestProcessor;
|
||||
import org.apache.rocketmq.remoting.netty.RemotingResponseCallback;
|
||||
@@ -63,7 +63,6 @@ import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
import org.apache.rocketmq.store.MessageExtBatch;
|
||||
import org.apache.rocketmq.store.MessageExtBrokerInner;
|
||||
import org.apache.rocketmq.store.PutMessageResult;
|
||||
import org.apache.rocketmq.store.StoreUtil;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
import org.apache.rocketmq.store.config.StorePathConfigHelper;
|
||||
import org.apache.rocketmq.store.stats.BrokerStatsManager;
|
||||
@@ -684,7 +683,7 @@ public class SendMessageProcessor extends AbstractSendMessageProcessor implement
|
||||
|
||||
CompletableFuture<PutMessageResult> putMessageResult;
|
||||
|
||||
if (StoreUtil.isStreamMode(this.brokerController.getMessageStore()) && MessageClientIDSetter.getUniqID(messageExtBatch) != null) {
|
||||
if (QueueTypeUtils.isBatchCq(Optional.of(topicConfig)) && MessageClientIDSetter.getUniqID(messageExtBatch) != null) {
|
||||
// newly introduced inner-batch message
|
||||
messageExtBatch.setSysFlag(messageExtBatch.getSysFlag() | MessageSysFlag.NEED_UNWRAP_FLAG);
|
||||
messageExtBatch.setSysFlag(messageExtBatch.getSysFlag() | MessageSysFlag.INNER_BATCH_FLAG);
|
||||
|
||||
@@ -24,9 +24,9 @@ import org.apache.rocketmq.common.TopicConfig;
|
||||
import org.apache.rocketmq.common.attribute.BooleanAttribute;
|
||||
import org.apache.rocketmq.common.attribute.EnumAttribute;
|
||||
import org.apache.rocketmq.common.attribute.LongRangeAttribute;
|
||||
import org.apache.rocketmq.common.utils.QueueTypeUtils;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
import org.apache.rocketmq.store.util.QueueTypeUtils;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -37,6 +37,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.google.common.collect.Sets.newHashSet;
|
||||
import static java.util.Arrays.asList;
|
||||
@@ -123,7 +124,7 @@ public class TopicConfigManagerTest {
|
||||
@Test
|
||||
public void testAddWrongValueOnCreating() {
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put("+" + TopicAttributes.QUEUE_TYPE.getName(), "wrong-value");
|
||||
attributes.put("+" + TopicAttributes.QUEUE_TYPE_ATTRIBUTE.getName(), "wrong-value");
|
||||
|
||||
TopicConfig topicConfig = new TopicConfig();
|
||||
topicConfig.setTopicName("new-topic");
|
||||
@@ -300,7 +301,7 @@ public class TopicConfigManagerTest {
|
||||
topicConfigManager.updateTopicConfig(topicConfig);
|
||||
|
||||
TopicConfig topicConfigUpdated = topicConfigManager.getTopicConfigTable().get(topic);
|
||||
Assert.assertEquals(CQType.SimpleCQ, QueueTypeUtils.getCQType(topicConfigUpdated));
|
||||
Assert.assertEquals(CQType.SimpleCQ, QueueTypeUtils.getCQType(Optional.of(topicConfigUpdated)));
|
||||
|
||||
Assert.assertEquals("true", topicConfigUpdated.getAttributes().get(unchangeable));
|
||||
}
|
||||
|
||||
@@ -22,29 +22,31 @@ import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.common.message.MessageQueue;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base interface for MQ management
|
||||
*/
|
||||
public interface MQAdmin {
|
||||
/**
|
||||
* Creates an topic
|
||||
*
|
||||
* @param key accesskey
|
||||
* @param key accesskey
|
||||
* @param newTopic topic name
|
||||
* @param queueNum topic's queue number
|
||||
* @param attributes
|
||||
*/
|
||||
void createTopic(final String key, final String newTopic, final int queueNum)
|
||||
void createTopic(final String key, final String newTopic, final int queueNum, Map<String, String> attributes)
|
||||
throws MQClientException;
|
||||
|
||||
/**
|
||||
* Creates an topic
|
||||
*
|
||||
* @param key accesskey
|
||||
* @param key accesskey
|
||||
* @param newTopic topic name
|
||||
* @param queueNum topic's queue number
|
||||
* @param topicSysFlag topic system flag
|
||||
* @param attributes
|
||||
*/
|
||||
void createTopic(String key, String newTopic, int queueNum, int topicSysFlag)
|
||||
void createTopic(String key, String newTopic, int queueNum, int topicSysFlag, Map<String, String> attributes)
|
||||
throws MQClientException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.apache.rocketmq.client.consumer;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.rocketmq.client.ClientConfig;
|
||||
import org.apache.rocketmq.client.QueryResult;
|
||||
@@ -124,8 +125,8 @@ public class DefaultMQPullConsumer extends ClientConfig implements MQPullConsume
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public void createTopic(String key, String newTopic, int queueNum) throws MQClientException {
|
||||
createTopic(key, withNamespace(newTopic), queueNum, 0);
|
||||
public void createTopic(String key, String newTopic, int queueNum, Map<String, String> attributes) throws MQClientException {
|
||||
createTopic(key, withNamespace(newTopic), queueNum, 0, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +134,7 @@ public class DefaultMQPullConsumer extends ClientConfig implements MQPullConsume
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException {
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag, Map<String, String> attributes) throws MQClientException {
|
||||
this.defaultMQPullConsumerImpl.createTopic(key, withNamespace(newTopic), queueNum, topicSysFlag);
|
||||
}
|
||||
|
||||
|
||||
@@ -431,8 +431,8 @@ public class DefaultMQPushConsumer extends ClientConfig implements MQPushConsume
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public void createTopic(String key, String newTopic, int queueNum) throws MQClientException {
|
||||
createTopic(key, withNamespace(newTopic), queueNum, 0);
|
||||
public void createTopic(String key, String newTopic, int queueNum, Map<String, String> attributes) throws MQClientException {
|
||||
createTopic(key, withNamespace(newTopic), queueNum, 0, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -448,7 +448,7 @@ public class DefaultMQPushConsumer extends ClientConfig implements MQPushConsume
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException {
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag, Map<String, String> attributes) throws MQClientException {
|
||||
this.defaultMQPushConsumerImpl.createTopic(key, withNamespace(newTopic), queueNum, topicSysFlag);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -76,10 +77,10 @@ public class MQAdminImpl {
|
||||
}
|
||||
|
||||
public void createTopic(String key, String newTopic, int queueNum) throws MQClientException {
|
||||
createTopic(key, newTopic, queueNum, 0);
|
||||
createTopic(key, newTopic, queueNum, 0, null);
|
||||
}
|
||||
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException {
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag, Map<String, String> attributes) throws MQClientException {
|
||||
try {
|
||||
Validators.checkTopic(newTopic);
|
||||
Validators.isSystemTopic(newTopic);
|
||||
@@ -100,6 +101,7 @@ public class MQAdminImpl {
|
||||
topicConfig.setReadQueueNums(queueNum);
|
||||
topicConfig.setWriteQueueNums(queueNum);
|
||||
topicConfig.setTopicSysFlag(topicSysFlag);
|
||||
topicConfig.setAttributes(attributes);
|
||||
|
||||
boolean createOK = false;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
|
||||
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException {
|
||||
this.isRunning();
|
||||
this.mQClientFactory.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag);
|
||||
this.mQClientFactory.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag, null);
|
||||
}
|
||||
|
||||
private void isRunning() throws MQClientException {
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ public class DefaultMQPushConsumerImpl implements MQConsumerInner {
|
||||
}
|
||||
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException {
|
||||
this.mQClientFactory.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag);
|
||||
this.mQClientFactory.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag, null);
|
||||
}
|
||||
|
||||
public Set<MessageQueue> fetchSubscribeMessageQueues(String topic) throws MQClientException {
|
||||
|
||||
+1
-1
@@ -447,7 +447,7 @@ public class DefaultMQProducerImpl implements MQProducerInner {
|
||||
Validators.checkTopic(newTopic);
|
||||
Validators.isSystemTopic(newTopic);
|
||||
|
||||
this.mQClientFactory.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag);
|
||||
this.mQClientFactory.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag, null);
|
||||
}
|
||||
|
||||
private void makeSureStateOK() throws MQClientException {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.apache.rocketmq.client.producer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -757,12 +758,13 @@ public class DefaultMQProducer extends ClientConfig implements MQProducer {
|
||||
* @param key accesskey
|
||||
* @param newTopic topic name
|
||||
* @param queueNum topic's queue number
|
||||
* @param attributes
|
||||
* @throws MQClientException if there is any client error.
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public void createTopic(String key, String newTopic, int queueNum) throws MQClientException {
|
||||
createTopic(key, withNamespace(newTopic), queueNum, 0);
|
||||
public void createTopic(String key, String newTopic, int queueNum, Map<String, String> attributes) throws MQClientException {
|
||||
createTopic(key, withNamespace(newTopic), queueNum, 0, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -773,11 +775,12 @@ public class DefaultMQProducer extends ClientConfig implements MQProducer {
|
||||
* @param newTopic topic name
|
||||
* @param queueNum topic's queue number
|
||||
* @param topicSysFlag topic system flag
|
||||
* @param attributes
|
||||
* @throws MQClientException if there is any client error.
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException {
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag, Map<String, String> attributes) throws MQClientException {
|
||||
this.defaultMQProducerImpl.createTopic(key, withNamespace(newTopic), queueNum, topicSysFlag);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Map;
|
||||
import static com.google.common.collect.Sets.newHashSet;
|
||||
|
||||
public class TopicAttributes {
|
||||
public static final EnumAttribute QUEUE_TYPE = new EnumAttribute(
|
||||
public static final EnumAttribute QUEUE_TYPE_ATTRIBUTE = new EnumAttribute(
|
||||
"queue.type",
|
||||
false,
|
||||
newHashSet("BatchCQ", "SimpleCQ"),
|
||||
@@ -35,6 +35,6 @@ public class TopicAttributes {
|
||||
|
||||
static {
|
||||
ALL = new HashMap<>();
|
||||
ALL.put(QUEUE_TYPE.getName(), QUEUE_TYPE);
|
||||
ALL.put(QUEUE_TYPE_ATTRIBUTE.getName(), QUEUE_TYPE_ATTRIBUTE);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.rocketmq.store.queue;
|
||||
package org.apache.rocketmq.common.attribute;
|
||||
|
||||
public enum CQType {
|
||||
SimpleCQ,
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.common.utils;
|
||||
|
||||
import org.apache.rocketmq.common.TopicAttributes;
|
||||
import org.apache.rocketmq.common.TopicConfig;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class QueueTypeUtils {
|
||||
|
||||
public static boolean isBatchCq(Optional<TopicConfig> topicConfig) {
|
||||
return Objects.equals(CQType.BatchCQ, getCQType(topicConfig));
|
||||
}
|
||||
|
||||
public static CQType getCQType(Optional<TopicConfig> topicConfig) {
|
||||
if (!topicConfig.isPresent()) {
|
||||
return CQType.valueOf(TopicAttributes.QUEUE_TYPE_ATTRIBUTE.getDefaultValue());
|
||||
}
|
||||
|
||||
String attributeName = TopicAttributes.QUEUE_TYPE_ATTRIBUTE.getName();
|
||||
|
||||
Map<String, String> attributes = topicConfig.get().getAttributes();
|
||||
if (attributes == null || attributes.size() == 0) {
|
||||
return CQType.valueOf(TopicAttributes.QUEUE_TYPE_ATTRIBUTE.getDefaultValue());
|
||||
}
|
||||
|
||||
if (attributes.containsKey(attributeName)) {
|
||||
return CQType.valueOf(attributes.get(attributeName));
|
||||
} else {
|
||||
return CQType.valueOf(TopicAttributes.QUEUE_TYPE_ATTRIBUTE.getDefaultValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,10 @@ import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -36,6 +36,7 @@ import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.rocketmq.common.ServiceThread;
|
||||
import org.apache.rocketmq.common.TopicConfig;
|
||||
import org.apache.rocketmq.common.UtilAll;
|
||||
import org.apache.rocketmq.common.constant.LoggerName;
|
||||
import org.apache.rocketmq.common.message.MessageAccessor;
|
||||
@@ -44,6 +45,7 @@ import org.apache.rocketmq.common.message.MessageDecoder;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
|
||||
import org.apache.rocketmq.common.topic.TopicValidator;
|
||||
import org.apache.rocketmq.common.utils.QueueTypeUtils;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.store.config.BrokerRole;
|
||||
@@ -51,9 +53,8 @@ import org.apache.rocketmq.store.config.FlushDiskType;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
import org.apache.rocketmq.store.ha.HAService;
|
||||
import org.apache.rocketmq.store.logfile.MappedFile;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.store.schedule.ScheduleMessageService;
|
||||
import org.apache.rocketmq.store.util.QueueTypeUtils;
|
||||
|
||||
/**
|
||||
* Store all metadata downtime for recovery, data protection reliability
|
||||
@@ -433,8 +434,8 @@ public class CommitLog implements Swappable {
|
||||
|
||||
private void setBatchSizeIfNeeded(Map<String, String> propertiesMap, DispatchRequest dispatchRequest) {
|
||||
if (null != propertiesMap && propertiesMap.containsKey(MessageConst.PROPERTY_INNER_NUM) && propertiesMap.containsKey(MessageConst.PROPERTY_INNER_BASE)) {
|
||||
dispatchRequest.setMsgBaseOffset(Long.valueOf(propertiesMap.get(MessageConst.PROPERTY_INNER_BASE)));
|
||||
dispatchRequest.setBatchSize(Short.valueOf(propertiesMap.get(MessageConst.PROPERTY_INNER_NUM)));
|
||||
dispatchRequest.setMsgBaseOffset(Long.parseLong(propertiesMap.get(MessageConst.PROPERTY_INNER_BASE)));
|
||||
dispatchRequest.setBatchSize(Short.parseShort(propertiesMap.get(MessageConst.PROPERTY_INNER_NUM)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -672,7 +673,7 @@ public class CommitLog implements Swappable {
|
||||
|
||||
topicQueueLock.lock(topicQueueKey);
|
||||
try {
|
||||
defaultMessageStore.assignOffset(topicQueueKey, msg, getBatchNum(msg));
|
||||
defaultMessageStore.assignOffset(topicQueueKey, msg, getMessageNum(msg));
|
||||
|
||||
PutMessageResult encodeResult = putMessageThreadLocal.getEncoder().encode(msg);
|
||||
if (encodeResult != null) {
|
||||
@@ -1031,15 +1032,6 @@ public class CommitLog implements Swappable {
|
||||
return this.mappedFileQueue.retryDeleteFirstFile(intervalForcibly);
|
||||
}
|
||||
|
||||
public void removeQueueFromTopicQueueTable(final String topic, final int queueId) {
|
||||
String key = topic + "-" + queueId;
|
||||
synchronized (this) {
|
||||
this.defaultMessageStore.removeOffsetTable(key);
|
||||
}
|
||||
|
||||
log.info("removeQueueFromTopicQueueTable OK Topic: {} QueueId: {}", topic, queueId);
|
||||
}
|
||||
|
||||
public void checkSelf() {
|
||||
mappedFileQueue.checkSelf();
|
||||
}
|
||||
@@ -1058,19 +1050,24 @@ public class CommitLog implements Swappable {
|
||||
return diff;
|
||||
}
|
||||
|
||||
protected short getBatchNum(MessageExtBrokerInner msgInner) {
|
||||
short batchNum = 1;
|
||||
protected short getMessageNum(MessageExtBrokerInner msgInner) {
|
||||
short messageNum = 1;
|
||||
// IF inner batch, build batchQueueOffset and batchNum property.
|
||||
CQType cqType = QueueTypeUtils.getCQType(defaultMessageStore);
|
||||
if (MessageSysFlag.check(msgInner.getSysFlag(), MessageSysFlag.INNER_BATCH_FLAG) || CQType.BatchCQ.equals(cqType)) {
|
||||
CQType cqType = getCqType(msgInner);
|
||||
|
||||
if (MessageSysFlag.check(msgInner.getSysFlag(), MessageSysFlag.INNER_BATCH_FLAG) || CQType.BatchCQ.equals(cqType)) {
|
||||
if (msgInner.getProperty(MessageConst.PROPERTY_INNER_NUM) != null) {
|
||||
batchNum = Short.parseShort(msgInner.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
batchNum = batchNum >= 1 ? batchNum : 1;
|
||||
messageNum = Short.parseShort(msgInner.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
messageNum = messageNum >= 1 ? messageNum : 1;
|
||||
}
|
||||
}
|
||||
|
||||
return batchNum;
|
||||
return messageNum;
|
||||
}
|
||||
|
||||
private CQType getCqType(MessageExtBrokerInner msgInner) {
|
||||
Optional<TopicConfig> topicConfig = this.defaultMessageStore.getTopicConfig(msgInner.getTopic());
|
||||
return QueueTypeUtils.getCQType(topicConfig);
|
||||
}
|
||||
|
||||
abstract class FlushCommitLogService extends ServiceThread {
|
||||
@@ -1488,7 +1485,7 @@ public class CommitLog implements Swappable {
|
||||
Long queueOffset = msgInner.getQueueOffset();
|
||||
|
||||
// this msg maybe a inner-batch msg.
|
||||
short batchNum = getBatchNum(msgInner);
|
||||
short messageNum = getMessageNum(msgInner);
|
||||
|
||||
// Transaction messages that require special handling
|
||||
final int tranType = MessageSysFlag.getTransactionValue(msgInner.getSysFlag());
|
||||
@@ -1545,7 +1542,7 @@ public class CommitLog implements Swappable {
|
||||
CommitLog.this.getMessageStore().getPerfCounter().endTick("WRITE_MEMORY_TIME_MS");
|
||||
msgInner.setEncodedBuff(null);
|
||||
return new AppendMessageResult(AppendMessageStatus.PUT_OK, wroteOffset, msgLen, msgIdSupplier,
|
||||
msgInner.getStoreTimestamp(), queueOffset, CommitLog.this.defaultMessageStore.now() - beginTimeMills, batchNum);
|
||||
msgInner.getStoreTimestamp(), queueOffset, CommitLog.this.defaultMessageStore.now() - beginTimeMills, messageNum);
|
||||
}
|
||||
|
||||
public AppendMessageResult doAppend(final long fileFromOffset, final ByteBuffer byteBuffer, final int maxBlank,
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.apache.rocketmq.store;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import org.apache.rocketmq.common.constant.LoggerName;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
@@ -25,10 +26,11 @@ import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.store.config.BrokerRole;
|
||||
import org.apache.rocketmq.store.config.StorePathConfigHelper;
|
||||
import org.apache.rocketmq.store.logfile.MappedFile;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.store.queue.ConsumeQueueInterface;
|
||||
import org.apache.rocketmq.store.queue.CqUnit;
|
||||
import org.apache.rocketmq.store.queue.FileQueueLifeCycle;
|
||||
import org.apache.rocketmq.store.queue.QueueOffsetAssigner;
|
||||
import org.apache.rocketmq.store.queue.ReferredIterator;
|
||||
|
||||
public class ConsumeQueue implements ConsumeQueueInterface, FileQueueLifeCycle {
|
||||
@@ -37,7 +39,7 @@ public class ConsumeQueue implements ConsumeQueueInterface, FileQueueLifeCycle {
|
||||
public static final int CQ_STORE_UNIT_SIZE = 20;
|
||||
private static final InternalLogger LOG_ERROR = InternalLoggerFactory.getLogger(LoggerName.STORE_ERROR_LOGGER_NAME);
|
||||
|
||||
private final DefaultMessageStore defaultMessageStore;
|
||||
private final MessageStore defaultMessageStore;
|
||||
|
||||
private final MappedFileQueue mappedFileQueue;
|
||||
private final String topic;
|
||||
@@ -55,7 +57,7 @@ public class ConsumeQueue implements ConsumeQueueInterface, FileQueueLifeCycle {
|
||||
final int queueId,
|
||||
final String storePath,
|
||||
final int mappedFileSize,
|
||||
final DefaultMessageStore defaultMessageStore) {
|
||||
final MessageStore defaultMessageStore) {
|
||||
this.storePath = storePath;
|
||||
this.mappedFileSize = mappedFileSize;
|
||||
this.defaultMessageStore = defaultMessageStore;
|
||||
@@ -438,6 +440,17 @@ public class ConsumeQueue implements ConsumeQueueInterface, FileQueueLifeCycle {
|
||||
this.defaultMessageStore.getRunningFlags().makeLogicsQueueError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assignQueueOffset(QueueOffsetAssigner queueOffsetAssigner, MessageExtBrokerInner msg, short messageNum) {
|
||||
String topicQueueKey = getTopic() + "-" + getQueueId();
|
||||
HashMap<String, Long> topicQueueTable = queueOffsetAssigner.getTopicQueueTable();
|
||||
|
||||
long topicOffset = topicQueueTable.computeIfAbsent(topicQueueKey, k -> 0L);
|
||||
topicQueueTable.put(topicQueueKey, topicOffset + messageNum);
|
||||
|
||||
msg.setQueueOffset(topicOffset);
|
||||
}
|
||||
|
||||
private boolean putMessagePositionInfo(final long offset, final int size, final long tagsCode,
|
||||
final long cqOffset) {
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
@@ -47,13 +47,16 @@ import org.apache.rocketmq.common.MixAll;
|
||||
import org.apache.rocketmq.common.ServiceThread;
|
||||
import org.apache.rocketmq.common.SystemClock;
|
||||
import org.apache.rocketmq.common.ThreadFactoryImpl;
|
||||
import org.apache.rocketmq.common.TopicConfig;
|
||||
import org.apache.rocketmq.common.UtilAll;
|
||||
import org.apache.rocketmq.common.constant.LoggerName;
|
||||
import org.apache.rocketmq.common.message.MessageConst;
|
||||
import org.apache.rocketmq.common.message.MessageDecoder;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.common.running.RunningStats;
|
||||
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
|
||||
import org.apache.rocketmq.common.topic.TopicValidator;
|
||||
import org.apache.rocketmq.common.utils.QueueTypeUtils;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.store.config.BrokerRole;
|
||||
@@ -74,8 +77,6 @@ import org.apache.rocketmq.store.schedule.ScheduleMessageService;
|
||||
import org.apache.rocketmq.store.stats.BrokerStatsManager;
|
||||
import org.apache.rocketmq.store.util.PerfCounter;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
public class DefaultMessageStore implements MessageStore {
|
||||
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.STORE_LOGGER_NAME);
|
||||
|
||||
@@ -87,10 +88,6 @@ public class DefaultMessageStore implements MessageStore {
|
||||
|
||||
private final ConsumeQueueStore consumeQueueStore;
|
||||
|
||||
private final ConcurrentMap<String/* topic */, ConcurrentMap<Integer/* queueId */, ConsumeQueueInterface>> consumeQueueTable;
|
||||
|
||||
protected HashMap<String/* topic-queueid */, Long/* offset */> topicQueueTable = new HashMap<>(1024);
|
||||
|
||||
private final FlushConsumeQueueService flushConsumeQueueService;
|
||||
|
||||
private final CleanCommitLogService cleanCommitLogService;
|
||||
@@ -154,8 +151,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
} else {
|
||||
this.commitLog = new CommitLog(this);
|
||||
}
|
||||
this.consumeQueueTable = new ConcurrentHashMap<>(32);
|
||||
this.consumeQueueStore = new ConsumeQueueStore(this, this.messageStoreConfig, this.consumeQueueTable);
|
||||
this.consumeQueueStore = new ConsumeQueueStore(this, this.messageStoreConfig);
|
||||
|
||||
this.flushConsumeQueueService = new FlushConsumeQueueService();
|
||||
this.cleanCommitLogService = new CleanCommitLogService();
|
||||
@@ -194,13 +190,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
|
||||
@Override
|
||||
public void truncateDirtyLogicFiles(long phyOffset) {
|
||||
ConcurrentMap<String, ConcurrentMap<Integer, ConsumeQueueInterface>> tables = DefaultMessageStore.this.consumeQueueTable;
|
||||
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : tables.values()) {
|
||||
for (ConsumeQueueInterface logic : maps.values()) {
|
||||
this.consumeQueueStore.truncateDirtyLogicFiles(logic, phyOffset);
|
||||
}
|
||||
}
|
||||
this.consumeQueueStore.truncateDirty(phyOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,7 +201,6 @@ public class DefaultMessageStore implements MessageStore {
|
||||
boolean result = true;
|
||||
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
boolean lastExitOK = !this.isTempFileExist();
|
||||
log.info("last shutdown {}, root dir: {}", lastExitOK ? "normally" : "abnormally", messageStoreConfig.getStorePathRootDir());
|
||||
|
||||
@@ -219,7 +208,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
result = result && this.commitLog.load();
|
||||
|
||||
// load Consume Queue
|
||||
result = result && this.loadConsumeQueue();
|
||||
result = result && this.consumeQueueStore.load();
|
||||
|
||||
if (result) {
|
||||
this.storeCheckpoint =
|
||||
@@ -269,7 +258,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
* 4. Make sure the fall-behind messages to be dispatched before starting the commitlog, especially when the broker role are automatically changed.
|
||||
*/
|
||||
long maxPhysicalPosInLogicQueue = commitLog.getMinOffset();
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : this.consumeQueueTable.values()) {
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : this.getConsumeQueueTable().values()) {
|
||||
for (ConsumeQueueInterface logic : maps.values()) {
|
||||
if (logic.getMaxPhysicOffset() > maxPhysicalPosInLogicQueue) {
|
||||
maxPhysicalPosInLogicQueue = logic.getMaxPhysicOffset();
|
||||
@@ -387,11 +376,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
|
||||
@Override
|
||||
public void destroyLogics() {
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : this.consumeQueueTable.values()) {
|
||||
for (ConsumeQueueInterface logic : maps.values()) {
|
||||
this.consumeQueueStore.destroy(logic);
|
||||
}
|
||||
}
|
||||
this.consumeQueueStore.destroy();
|
||||
}
|
||||
|
||||
private PutMessageStatus checkMessage(MessageExtBrokerInner msg) {
|
||||
@@ -464,6 +449,20 @@ public class DefaultMessageStore implements MessageStore {
|
||||
return CompletableFuture.completedFuture(new PutMessageResult(msgCheckStatus, null));
|
||||
}
|
||||
|
||||
if (msg.getProperties().containsKey(MessageConst.PROPERTY_INNER_NUM)
|
||||
&& !MessageSysFlag.check(msg.getSysFlag(), MessageSysFlag.INNER_BATCH_FLAG)) {
|
||||
log.warn("[BUG]The message had property {} but is not an inner batch", MessageConst.PROPERTY_INNER_NUM);
|
||||
return CompletableFuture.completedFuture(new PutMessageResult(PutMessageStatus.MESSAGE_ILLEGAL, null));
|
||||
}
|
||||
|
||||
if (MessageSysFlag.check(msg.getSysFlag(), MessageSysFlag.INNER_BATCH_FLAG)) {
|
||||
Optional<TopicConfig> topicConfig = this.getTopicConfig(msg.getTopic());
|
||||
if (!QueueTypeUtils.isBatchCq(topicConfig)) {
|
||||
log.error("[BUG]The message is an inner batch but cq type is not batch cq");
|
||||
return CompletableFuture.completedFuture(new PutMessageResult(PutMessageStatus.MESSAGE_ILLEGAL, null));
|
||||
}
|
||||
}
|
||||
|
||||
long beginTime = this.getSystemClock().now();
|
||||
CompletableFuture<PutMessageResult> putResultFuture = this.commitLog.asyncPutMessage(msg);
|
||||
|
||||
@@ -649,8 +648,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.isTheBatchFull(sizePy, maxMsgNums, maxPullSize, getResult.getBufferTotalSize(), getResult.getMessageCount(),
|
||||
isInDisk)) {
|
||||
if (this.isTheBatchFull(sizePy, cqUnit.getBatchNum(), maxMsgNums, maxPullSize, getResult.getBufferTotalSize(), getResult.getMessageCount(), isInDisk)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -756,7 +754,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
return logic.getMaxOffsetInQueue();
|
||||
}
|
||||
} else {
|
||||
Long offset = this.topicQueueTable.get(topic + "-" + queueId);
|
||||
Long offset = this.consumeQueueStore.getMaxOffset(topic, queueId);
|
||||
if (offset != null) {
|
||||
return offset;
|
||||
}
|
||||
@@ -800,7 +798,11 @@ public class DefaultMessageStore implements MessageStore {
|
||||
public long getOffsetInQueueByTime(String topic, int queueId, long timestamp) {
|
||||
ConsumeQueueInterface logic = this.findConsumeQueue(topic, queueId);
|
||||
if (logic != null) {
|
||||
return logic.getOffsetInQueueByTime(timestamp);
|
||||
long resultOffset = logic.getOffsetInQueueByTime(timestamp);
|
||||
// Make sure the result offset is in valid range.
|
||||
resultOffset = Math.max(resultOffset, logic.getMinOffsetInQueue());
|
||||
resultOffset = Math.min(resultOffset, logic.getMaxOffsetInQueue());
|
||||
return resultOffset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1071,7 +1073,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
|
||||
@Override
|
||||
public int cleanUnusedTopic(Set<String> topics) {
|
||||
Iterator<Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>>> it = this.consumeQueueTable.entrySet().iterator();
|
||||
Iterator<Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>>> it = this.getConsumeQueueTable().entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>> next = it.next();
|
||||
String topic = next.getKey();
|
||||
@@ -1086,7 +1088,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
cq.getQueueId()
|
||||
);
|
||||
|
||||
this.commitLog.removeQueueFromTopicQueueTable(cq.getTopic(), cq.getQueueId());
|
||||
this.consumeQueueStore.removeTopicQueueTable(cq.getTopic(), cq.getQueueId());
|
||||
}
|
||||
it.remove();
|
||||
|
||||
@@ -1105,45 +1107,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
public void cleanExpiredConsumerQueue() {
|
||||
long minCommitLogOffset = this.commitLog.getMinOffset();
|
||||
|
||||
Iterator<Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>>> it = this.consumeQueueTable.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>> next = it.next();
|
||||
String topic = next.getKey();
|
||||
if (!topic.equals(TopicValidator.RMQ_SYS_SCHEDULE_TOPIC)) {
|
||||
ConcurrentMap<Integer, ConsumeQueueInterface> queueTable = next.getValue();
|
||||
Iterator<Entry<Integer, ConsumeQueueInterface>> itQT = queueTable.entrySet().iterator();
|
||||
while (itQT.hasNext()) {
|
||||
Entry<Integer, ConsumeQueueInterface> nextQT = itQT.next();
|
||||
long maxCLOffsetInConsumeQueue = nextQT.getValue().getLastOffset();
|
||||
|
||||
if (maxCLOffsetInConsumeQueue == -1) {
|
||||
log.warn("maybe ConsumeQueue was created just now. topic={} queueId={} maxPhysicOffset={} minLogicOffset={}.",
|
||||
nextQT.getValue().getTopic(),
|
||||
nextQT.getValue().getQueueId(),
|
||||
nextQT.getValue().getMaxPhysicOffset(),
|
||||
nextQT.getValue().getMinLogicOffset());
|
||||
} else if (maxCLOffsetInConsumeQueue < minCommitLogOffset) {
|
||||
log.info(
|
||||
"cleanExpiredConsumerQueue: {} {} consumer queue destroyed, minCommitLogOffset: {} maxCLOffsetInConsumeQueue: {}",
|
||||
topic,
|
||||
nextQT.getKey(),
|
||||
minCommitLogOffset,
|
||||
maxCLOffsetInConsumeQueue);
|
||||
|
||||
DefaultMessageStore.this.commitLog.removeQueueFromTopicQueueTable(nextQT.getValue().getTopic(),
|
||||
nextQT.getValue().getQueueId());
|
||||
|
||||
this.consumeQueueStore.destroy(nextQT.getValue());
|
||||
itQT.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (queueTable.isEmpty()) {
|
||||
log.info("cleanExpiredConsumerQueue: {},topic destroyed", topic);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.consumeQueueStore.cleanExpired(minCommitLogOffset);
|
||||
}
|
||||
|
||||
public Map<String, Long> getMessageIds(final String topic, final int queueId, long minOffset, long maxOffset,
|
||||
@@ -1269,13 +1233,13 @@ public class DefaultMessageStore implements MessageStore {
|
||||
return (maxOffsetPy - offsetPy) > memory;
|
||||
}
|
||||
|
||||
private boolean isTheBatchFull(int sizePy, int maxMsgNums, long maxMsgSize, int bufferTotal, int messageTotal, boolean isInDisk) {
|
||||
private boolean isTheBatchFull(int sizePy, int unitBatchNum, int maxMsgNums, long maxMsgSize, int bufferTotal, int messageTotal, boolean isInDisk) {
|
||||
|
||||
if (0 == bufferTotal || 0 == messageTotal) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (maxMsgNums <= messageTotal) {
|
||||
if (messageTotal + unitBatchNum > maxMsgNums) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1392,16 +1356,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
|
||||
private void checkSelf() {
|
||||
this.commitLog.checkSelf();
|
||||
|
||||
Iterator<Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>>> it = this.consumeQueueTable.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>> next = it.next();
|
||||
Iterator<Entry<Integer, ConsumeQueueInterface>> itNext = next.getValue().entrySet().iterator();
|
||||
while (itNext.hasNext()) {
|
||||
Entry<Integer, ConsumeQueueInterface> cq = itNext.next();
|
||||
this.consumeQueueStore.checkSelf(cq.getValue());
|
||||
}
|
||||
}
|
||||
this.consumeQueueStore.checkSelf();
|
||||
}
|
||||
|
||||
private boolean isTempFileExist() {
|
||||
@@ -1410,53 +1365,6 @@ public class DefaultMessageStore implements MessageStore {
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
private boolean loadConsumeQueue() {
|
||||
checkOtherConsumeQueue();
|
||||
|
||||
File dirLogic = new File(StorePathConfigHelper.getStorePathConsumeQueue(this.messageStoreConfig.getStorePathRootDir()));
|
||||
File[] fileTopicList = dirLogic.listFiles();
|
||||
if (fileTopicList != null) {
|
||||
|
||||
for (File fileTopic : fileTopicList) {
|
||||
String topic = fileTopic.getName();
|
||||
|
||||
File[] fileQueueIdList = fileTopic.listFiles();
|
||||
if (fileQueueIdList != null) {
|
||||
for (File fileQueueId : fileQueueIdList) {
|
||||
int queueId;
|
||||
try {
|
||||
queueId = Integer.parseInt(fileQueueId.getName());
|
||||
} catch (NumberFormatException e) {
|
||||
continue;
|
||||
}
|
||||
ConsumeQueueInterface logic = new ConsumeQueue(
|
||||
topic,
|
||||
queueId,
|
||||
StorePathConfigHelper.getStorePathConsumeQueue(this.messageStoreConfig.getStorePathRootDir()),
|
||||
this.getMessageStoreConfig().getMappedFileSizeConsumeQueue(),
|
||||
this);
|
||||
this.putConsumeQueue(topic, queueId, logic);
|
||||
if (!this.consumeQueueStore.load(logic)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("load logics queue all over, OK");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void checkOtherConsumeQueue() {
|
||||
File dirLogic = new File(StorePathConfigHelper.getStorePathBatchConsumeQueue(this.messageStoreConfig.getStorePathRootDir()));
|
||||
if (dirLogic.exists()) {
|
||||
throw new RuntimeException(format("Batch consume queue directory: [%s] exist. Can not load consume queue while batch consume queue exists.",
|
||||
StorePathConfigHelper.getStorePathBatchConsumeQueue(this.messageStoreConfig.getStorePathRootDir())));
|
||||
}
|
||||
}
|
||||
|
||||
private void recover(final boolean lastExitOK) {
|
||||
long recoverCqStart = System.currentTimeMillis();
|
||||
long maxPhyOffsetOfConsumeQueue = this.recoverConsumeQueue();
|
||||
@@ -1485,43 +1393,13 @@ public class DefaultMessageStore implements MessageStore {
|
||||
return transientStorePool;
|
||||
}
|
||||
|
||||
private void putConsumeQueue(final String topic, final int queueId, final ConsumeQueueInterface consumeQueue) {
|
||||
ConcurrentMap<Integer/* queueId */, ConsumeQueueInterface> map = this.consumeQueueTable.get(topic);
|
||||
if (null == map) {
|
||||
map = new ConcurrentHashMap<Integer/* queueId */, ConsumeQueueInterface>();
|
||||
map.put(queueId, consumeQueue);
|
||||
this.consumeQueueTable.put(topic, map);
|
||||
} else {
|
||||
map.put(queueId, consumeQueue);
|
||||
}
|
||||
}
|
||||
|
||||
private long recoverConsumeQueue() {
|
||||
long maxPhysicOffset = -1;
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : this.consumeQueueTable.values()) {
|
||||
for (ConsumeQueueInterface logic : maps.values()) {
|
||||
this.consumeQueueStore.recover(logic);
|
||||
if (logic.getMaxPhysicOffset() > maxPhysicOffset) {
|
||||
maxPhysicOffset = logic.getMaxPhysicOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxPhysicOffset;
|
||||
return this.consumeQueueStore.recover();
|
||||
}
|
||||
|
||||
public void recoverTopicQueueTable() {
|
||||
HashMap<String/* topic-queueid */, Long/* offset */> table = new HashMap<String, Long>(1024);
|
||||
long minPhyOffset = this.commitLog.getMinOffset();
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : this.consumeQueueTable.values()) {
|
||||
for (ConsumeQueueInterface logic : maps.values()) {
|
||||
String key = logic.getTopic() + "-" + logic.getQueueId();
|
||||
table.put(key, logic.getMaxOffsetInQueue());
|
||||
this.consumeQueueStore.correctMinOffset(logic, minPhyOffset);
|
||||
}
|
||||
}
|
||||
|
||||
this.topicQueueTable = table;
|
||||
this.consumeQueueStore.recoverOffsetTable(minPhyOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1539,7 +1417,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
}
|
||||
|
||||
public ConcurrentMap<String, ConcurrentMap<Integer, ConsumeQueueInterface>> getConsumeQueueTable() {
|
||||
return consumeQueueTable;
|
||||
return consumeQueueStore.getConsumeQueueTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1569,8 +1447,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
}
|
||||
|
||||
public void putMessagePositionInfo(DispatchRequest dispatchRequest) {
|
||||
ConsumeQueueInterface cq = this.findConsumeQueue(dispatchRequest.getTopic(), dispatchRequest.getQueueId());
|
||||
this.consumeQueueStore.putMessagePositionInfoWrapper(cq, dispatchRequest);
|
||||
this.consumeQueueStore.putMessagePositionInfoWrapper(dispatchRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1606,7 +1483,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
|
||||
@Override
|
||||
public ConsumeQueueInterface getConsumeQueue(String topic, int queueId) {
|
||||
ConcurrentMap<Integer, ConsumeQueueInterface> map = consumeQueueTable.get(topic);
|
||||
ConcurrentMap<Integer, ConsumeQueueInterface> map = this.getConsumeQueueTable().get(topic);
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -1656,19 +1533,21 @@ public class DefaultMessageStore implements MessageStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assignOffset(String topicQueueKey, MessageExtBrokerInner msg, short batchNum) {
|
||||
public void assignOffset(String topicQueueKey, MessageExtBrokerInner msg, short messageNum) {
|
||||
final int tranType = MessageSysFlag.getTransactionValue(msg.getSysFlag());
|
||||
|
||||
if (tranType == MessageSysFlag.TRANSACTION_NOT_TYPE || tranType == MessageSysFlag.TRANSACTION_COMMIT_TYPE) {
|
||||
long topicOffset = this.topicQueueTable.computeIfAbsent(topicQueueKey, k -> 0L);
|
||||
msg.setQueueOffset(topicOffset);
|
||||
this.topicQueueTable.put(topicQueueKey, topicOffset + batchNum);
|
||||
this.consumeQueueStore.assignQueueOffset(msg, messageNum);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeOffsetTable(String topicQueueKey) {
|
||||
this.topicQueueTable.remove(topicQueueKey);
|
||||
public Optional<TopicConfig> getTopicConfig(String topic) {
|
||||
return this.consumeQueueStore.getTopicConfig(topic);
|
||||
}
|
||||
|
||||
public void setTopicConfigTable(ConcurrentMap<String, TopicConfig> topicConfigTable) {
|
||||
this.consumeQueueStore.setTopicConfigTable(topicConfigTable);
|
||||
}
|
||||
|
||||
class CommitLogDispatcherBuildConsumeQueue implements CommitLogDispatcher {
|
||||
@@ -1975,7 +1854,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
if (minOffset > this.lastPhysicalMinOffset) {
|
||||
this.lastPhysicalMinOffset = minOffset;
|
||||
|
||||
ConcurrentMap<String, ConcurrentMap<Integer, ConsumeQueueInterface>> tables = DefaultMessageStore.this.consumeQueueTable;
|
||||
ConcurrentMap<String, ConcurrentMap<Integer, ConsumeQueueInterface>> tables = DefaultMessageStore.this.getConsumeQueueTable();
|
||||
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : tables.values()) {
|
||||
for (ConsumeQueueInterface logic : maps.values()) {
|
||||
@@ -2021,7 +1900,7 @@ public class DefaultMessageStore implements MessageStore {
|
||||
logicsMsgTimestamp = DefaultMessageStore.this.getStoreCheckpoint().getLogicsMsgTimestamp();
|
||||
}
|
||||
|
||||
ConcurrentMap<String, ConcurrentMap<Integer, ConsumeQueueInterface>> tables = DefaultMessageStore.this.consumeQueueTable;
|
||||
ConcurrentMap<String, ConcurrentMap<Integer, ConsumeQueueInterface>> tables = DefaultMessageStore.this.getConsumeQueueTable();
|
||||
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : tables.values()) {
|
||||
for (ConsumeQueueInterface cq : maps.values()) {
|
||||
|
||||
@@ -171,8 +171,8 @@ public class MappedFileQueue implements Swappable {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
MappedFile mappedFile = new DefaultMappedFile(file.getPath(), mappedFileSize);
|
||||
try {
|
||||
MappedFile mappedFile = new DefaultMappedFile(file.getPath(), mappedFileSize);
|
||||
|
||||
mappedFile.setWrotePosition(this.mappedFileSize);
|
||||
mappedFile.setFlushedPosition(this.mappedFileSize);
|
||||
@@ -234,13 +234,13 @@ public class MappedFileQueue implements Swappable {
|
||||
if (this.allocateMappedFileService != null) {
|
||||
mappedFile = this.allocateMappedFileService.putRequestAndReturnMappedFile(nextFilePath,
|
||||
nextNextFilePath, this.mappedFileSize);
|
||||
} else {
|
||||
try {
|
||||
mappedFile = new DefaultMappedFile(nextFilePath, this.mappedFileSize);
|
||||
} catch (IOException e) {
|
||||
log.error("create mappedFile exception", e);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
mappedFile = new DefaultMappedFile(nextFilePath, this.mappedFileSize);
|
||||
} catch (IOException e) {
|
||||
log.error("create mappedFile exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (mappedFile != null) {
|
||||
if (this.mappedFiles.isEmpty()) {
|
||||
|
||||
@@ -18,10 +18,12 @@ package org.apache.rocketmq.store;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.apache.rocketmq.common.SystemClock;
|
||||
import org.apache.rocketmq.common.TopicConfig;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.store.config.BrokerRole;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
@@ -562,16 +564,19 @@ public interface MessageStore {
|
||||
boolean isSyncMaster();
|
||||
|
||||
/**
|
||||
* assign an queue offset and increase it.
|
||||
* Assign an queue offset and increase it.
|
||||
* If there is a race condition, you need to lock/unlock this method yourself.
|
||||
*
|
||||
* @param topicQueueKey topic-queue key
|
||||
* @param msg message
|
||||
* @param batchNum batch num
|
||||
* @param messageNum message num
|
||||
*/
|
||||
void assignOffset(String topicQueueKey, MessageExtBrokerInner msg, short batchNum);
|
||||
void assignOffset(String topicQueueKey, MessageExtBrokerInner msg, short messageNum);
|
||||
|
||||
/**
|
||||
* remove offset table
|
||||
* @param topicQueueKey topic-queue key
|
||||
* get topic config
|
||||
* @param topic topic name
|
||||
* @return topic config info
|
||||
*/
|
||||
void removeOffsetTable(String topicQueueKey);
|
||||
Optional<TopicConfig> getTopicConfig(String topic);
|
||||
}
|
||||
|
||||
@@ -8,40 +8,41 @@
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.rocketmq.store;
|
||||
|
||||
public class PutMessageContext {
|
||||
private String topicQueueTableKey;
|
||||
private long[] phyPos;
|
||||
private int batchSize;
|
||||
private String topicQueueTableKey;
|
||||
private long[] phyPos;
|
||||
private int batchSize;
|
||||
|
||||
public PutMessageContext(String topicQueueTableKey) {
|
||||
this.topicQueueTableKey = topicQueueTableKey;
|
||||
}
|
||||
public PutMessageContext(String topicQueueTableKey) {
|
||||
this.topicQueueTableKey = topicQueueTableKey;
|
||||
}
|
||||
|
||||
public String getTopicQueueTableKey() {
|
||||
return topicQueueTableKey;
|
||||
}
|
||||
public String getTopicQueueTableKey() {
|
||||
return topicQueueTableKey;
|
||||
}
|
||||
|
||||
public long[] getPhyPos() {
|
||||
return phyPos;
|
||||
}
|
||||
public long[] getPhyPos() {
|
||||
return phyPos;
|
||||
}
|
||||
|
||||
public void setPhyPos(long[] phyPos) {
|
||||
this.phyPos = phyPos;
|
||||
}
|
||||
public void setPhyPos(long[] phyPos) {
|
||||
this.phyPos = phyPos;
|
||||
}
|
||||
|
||||
public int getBatchSize() {
|
||||
return batchSize;
|
||||
}
|
||||
public int getBatchSize() {
|
||||
return batchSize;
|
||||
}
|
||||
|
||||
public void setBatchSize(int batchSize) {
|
||||
this.batchSize = batchSize;
|
||||
}
|
||||
}
|
||||
public void setBatchSize(int batchSize) {
|
||||
this.batchSize = batchSize;
|
||||
}
|
||||
}
|
||||
@@ -44,10 +44,6 @@ public class StoreUtil {
|
||||
return physicalTotal;
|
||||
}
|
||||
|
||||
public static boolean isStreamMode(MessageStore messageStore) {
|
||||
return messageStore instanceof StreamMessageStore;
|
||||
}
|
||||
|
||||
public static void fileAppend(MappedFile file, ByteBuffer data) {
|
||||
boolean success = file.appendMessage(data);
|
||||
if (!success) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,12 +8,13 @@
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.rocketmq.store;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.apache.rocketmq.store.config;
|
||||
import org.apache.rocketmq.common.annotation.ImportantField;
|
||||
import org.apache.rocketmq.store.ConsumeQueue;
|
||||
import org.apache.rocketmq.store.queue.BatchConsumeQueue;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -206,9 +205,6 @@ public class MessageStoreConfig {
|
||||
@ImportantField
|
||||
private boolean enableCleanExpiredOffset = false;
|
||||
|
||||
@ImportantField
|
||||
private String defaultCQType = CQType.SimpleCQ.toString();
|
||||
|
||||
private int maxAsyncPutMessageRequests = 5000;
|
||||
|
||||
private int pullBatchMaxMessageCount = 160;
|
||||
@@ -799,13 +795,6 @@ public class MessageStoreConfig {
|
||||
this.enableCleanExpiredOffset = enableCleanExpiredOffset;
|
||||
}
|
||||
|
||||
public String getDefaultCQType() {
|
||||
return defaultCQType;
|
||||
}
|
||||
|
||||
public void setDefaultCQType(String defaultCQType) {
|
||||
this.defaultCQType = defaultCQType;
|
||||
}
|
||||
public String getReadOnlyCommitLogStorePaths() {
|
||||
return readOnlyCommitLogStorePaths;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import io.openmessaging.storage.dledger.utils.DLedgerUtils;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -431,7 +430,7 @@ public class DLedgerCommitLog extends CommitLog {
|
||||
String topicQueueKey = msg.getTopic() + "-" + msg.getQueueId();
|
||||
topicQueueLock.lock(topicQueueKey);
|
||||
try {
|
||||
defaultMessageStore.assignOffset(topicQueueKey, msg, getBatchNum(msg));
|
||||
defaultMessageStore.assignOffset(topicQueueKey, msg, getMessageNum(msg));
|
||||
|
||||
encodeResult = this.messageSerializer.serialize(msg);
|
||||
if (encodeResult.status != AppendMessageStatus.PUT_OK) {
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.apache.rocketmq.store.logfile;
|
||||
|
||||
import org.apache.rocketmq.store.AppendMessageCallback;
|
||||
import org.apache.rocketmq.store.AppendMessageResult;
|
||||
import org.apache.rocketmq.store.CommitLog;
|
||||
import org.apache.rocketmq.store.MessageExtBatch;
|
||||
import org.apache.rocketmq.store.MessageExtBrokerInner;
|
||||
import org.apache.rocketmq.store.PutMessageContext;
|
||||
|
||||
@@ -17,11 +17,17 @@
|
||||
|
||||
package org.apache.rocketmq.store.queue;
|
||||
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.common.constant.LoggerName;
|
||||
import org.apache.rocketmq.common.message.MessageAccessor;
|
||||
import org.apache.rocketmq.common.message.MessageConst;
|
||||
import org.apache.rocketmq.common.message.MessageDecoder;
|
||||
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.store.DispatchRequest;
|
||||
import org.apache.rocketmq.store.MappedFileQueue;
|
||||
import org.apache.rocketmq.store.MessageExtBrokerInner;
|
||||
import org.apache.rocketmq.store.MessageStore;
|
||||
import org.apache.rocketmq.store.SelectMappedBufferResult;
|
||||
import org.apache.rocketmq.store.config.BrokerRole;
|
||||
@@ -29,6 +35,7 @@ import org.apache.rocketmq.store.logfile.MappedFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
@@ -386,9 +393,9 @@ public class BatchConsumeQueue implements ConsumeQueueInterface, FileQueueLifeCy
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteExpiredFile(long offset) {
|
||||
int cnt = this.mappedFileQueue.deleteExpiredFileByOffset(offset, CQ_STORE_UNIT_SIZE);
|
||||
this.correctMinOffset(offset);
|
||||
public int deleteExpiredFile(long minCommitLogPos) {
|
||||
int cnt = this.mappedFileQueue.deleteExpiredFileByOffset(minCommitLogPos, CQ_STORE_UNIT_SIZE);
|
||||
this.correctMinOffset(minCommitLogPos);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@@ -473,6 +480,21 @@ public class BatchConsumeQueue implements ConsumeQueueInterface, FileQueueLifeCy
|
||||
this.defaultMessageStore.getRunningFlags().makeLogicsQueueError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assignQueueOffset(QueueOffsetAssigner queueOffsetAssigner, MessageExtBrokerInner msg, short messageNum) {
|
||||
HashMap<String, Long> batchTopicQueueTable = queueOffsetAssigner.getBatchTopicQueueTable();
|
||||
String topicQueueKey = getTopic() + "-" + getQueueId();
|
||||
|
||||
Long topicOffset = batchTopicQueueTable.computeIfAbsent(topicQueueKey, k -> 0L);
|
||||
|
||||
if (MessageSysFlag.check(msg.getSysFlag(), MessageSysFlag.INNER_BATCH_FLAG)) {
|
||||
MessageAccessor.putProperty(msg, MessageConst.PROPERTY_INNER_BASE, String.valueOf(topicOffset));
|
||||
msg.setPropertiesString(MessageDecoder.messageProperties2String(msg.getProperties()));
|
||||
}
|
||||
msg.setQueueOffset(topicOffset);
|
||||
batchTopicQueueTable.put(topicQueueKey, topicOffset + messageNum);
|
||||
}
|
||||
|
||||
boolean putBatchMessagePositionInfo(final long offset, final int size, final long tagsCode, final long storeTime,
|
||||
final long msgBaseOffset, final short batchSize) {
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package org.apache.rocketmq.store.queue;
|
||||
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
|
||||
public interface ConsumeQueueInterface {
|
||||
/**
|
||||
* Get the topic name
|
||||
|
||||
@@ -16,27 +16,49 @@
|
||||
*/
|
||||
package org.apache.rocketmq.store.queue;
|
||||
|
||||
import org.apache.rocketmq.common.TopicConfig;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.common.constant.LoggerName;
|
||||
import org.apache.rocketmq.common.topic.TopicValidator;
|
||||
import org.apache.rocketmq.common.utils.QueueTypeUtils;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.store.ConsumeQueue;
|
||||
import org.apache.rocketmq.store.DefaultMessageStore;
|
||||
import org.apache.rocketmq.store.DispatchRequest;
|
||||
import org.apache.rocketmq.store.MessageExtBrokerInner;
|
||||
import org.apache.rocketmq.store.MessageStore;
|
||||
import org.apache.rocketmq.store.StoreUtil;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
import org.apache.rocketmq.store.config.StorePathConfigHelper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class ConsumeQueueStore {
|
||||
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.STORE_LOGGER_NAME);
|
||||
|
||||
protected final MessageStore messageStore;
|
||||
protected final MessageStoreConfig messageStoreConfig;
|
||||
protected final QueueOffsetAssigner queueOffsetAssigner = new QueueOffsetAssigner();
|
||||
protected final ConcurrentMap<String/* topic */, ConcurrentMap<Integer/* queueId */, ConsumeQueueInterface>> consumeQueueTable;
|
||||
|
||||
public ConsumeQueueStore(MessageStore messageStore, MessageStoreConfig messageStoreConfig, ConcurrentMap<String, ConcurrentMap<Integer, ConsumeQueueInterface>> consumeQueueTable) {
|
||||
// Should be careful, do not change the topic config
|
||||
// TopicConfigManager is more suitable here.
|
||||
private ConcurrentMap<String, TopicConfig> topicConfigTable;
|
||||
|
||||
public ConsumeQueueStore(MessageStore messageStore, MessageStoreConfig messageStoreConfig) {
|
||||
this.messageStore = messageStore;
|
||||
this.messageStoreConfig = messageStoreConfig;
|
||||
this.consumeQueueTable = consumeQueueTable;
|
||||
this.consumeQueueTable = new ConcurrentHashMap<>(32);
|
||||
}
|
||||
|
||||
public void setTopicConfigTable(ConcurrentMap<String, TopicConfig> topicConfigTable) {
|
||||
this.topicConfigTable = topicConfigTable;
|
||||
}
|
||||
|
||||
private FileQueueLifeCycle getLifeCycle(String topic, int queueId) {
|
||||
@@ -64,21 +86,143 @@ public class ConsumeQueueStore {
|
||||
fileQueueLifeCycle.putMessagePositionInfoWrapper(request);
|
||||
}
|
||||
|
||||
public void putMessagePositionInfoWrapper(DispatchRequest dispatchRequest) {
|
||||
ConsumeQueueInterface cq = this.findOrCreateConsumeQueue(dispatchRequest.getTopic(), dispatchRequest.getQueueId());
|
||||
this.putMessagePositionInfoWrapper(cq, dispatchRequest);
|
||||
}
|
||||
|
||||
public boolean load(ConsumeQueueInterface consumeQueue) {
|
||||
FileQueueLifeCycle fileQueueLifeCycle = getLifeCycle(consumeQueue.getTopic(), consumeQueue.getQueueId());
|
||||
return fileQueueLifeCycle.load();
|
||||
}
|
||||
|
||||
public boolean load() {
|
||||
return loadConsumeQueues() && loadBatchConsumeQueues();
|
||||
}
|
||||
|
||||
private boolean loadBatchConsumeQueues() {
|
||||
File dirLogic = new File(StorePathConfigHelper.getStorePathBatchConsumeQueue(this.messageStoreConfig.getStorePathRootDir()));
|
||||
File[] fileTopicList = dirLogic.listFiles();
|
||||
if (fileTopicList != null) {
|
||||
|
||||
for (File fileTopic : fileTopicList) {
|
||||
String topic = fileTopic.getName();
|
||||
|
||||
File[] fileQueueIdList = fileTopic.listFiles();
|
||||
if (fileQueueIdList != null) {
|
||||
for (File fileQueueId : fileQueueIdList) {
|
||||
int queueId;
|
||||
try {
|
||||
queueId = Integer.parseInt(fileQueueId.getName());
|
||||
} catch (NumberFormatException e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TopicConfig topicConfig = this.topicConfigTable == null ? null : this.topicConfigTable.get(topic);
|
||||
|
||||
// For batch consume queue, the topic config must exist
|
||||
if (topicConfig == null) {
|
||||
log.warn("topic: {} has no topic config.", topic);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Objects.equals(CQType.BatchCQ, QueueTypeUtils.getCQType(Optional.of(topicConfig)))) {
|
||||
log.error("[BUG]topic: {} should be BCQ.", topic);
|
||||
}
|
||||
|
||||
ConsumeQueueInterface logic = new BatchConsumeQueue(
|
||||
topic,
|
||||
queueId,
|
||||
StorePathConfigHelper.getStorePathBatchConsumeQueue(this.messageStoreConfig.getStorePathRootDir()),
|
||||
this.messageStoreConfig.getMappedFileSizeConsumeQueue(),
|
||||
this.messageStore);
|
||||
this.putConsumeQueue(topic, queueId, logic);
|
||||
if (!this.load(logic)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("load batch consume queue all over, OK");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean loadConsumeQueues() {
|
||||
File dirLogic = new File(StorePathConfigHelper.getStorePathConsumeQueue(this.messageStoreConfig.getStorePathRootDir()));
|
||||
File[] fileTopicList = dirLogic.listFiles();
|
||||
if (fileTopicList != null) {
|
||||
|
||||
for (File fileTopic : fileTopicList) {
|
||||
String topic = fileTopic.getName();
|
||||
|
||||
File[] fileQueueIdList = fileTopic.listFiles();
|
||||
if (fileQueueIdList != null) {
|
||||
for (File fileQueueId : fileQueueIdList) {
|
||||
int queueId;
|
||||
try {
|
||||
queueId = Integer.parseInt(fileQueueId.getName());
|
||||
} catch (NumberFormatException e) {
|
||||
continue;
|
||||
}
|
||||
ConsumeQueueInterface logic = new ConsumeQueue(
|
||||
topic,
|
||||
queueId,
|
||||
StorePathConfigHelper.getStorePathConsumeQueue(this.messageStoreConfig.getStorePathRootDir()),
|
||||
this.messageStoreConfig.getMappedFileSizeConsumeQueue(),
|
||||
this.messageStore);
|
||||
this.putConsumeQueue(topic, queueId, logic);
|
||||
if (!this.load(logic)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("load logics queue all over, OK");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void recover(ConsumeQueueInterface consumeQueue) {
|
||||
FileQueueLifeCycle fileQueueLifeCycle = getLifeCycle(consumeQueue.getTopic(), consumeQueue.getQueueId());
|
||||
fileQueueLifeCycle.recover();
|
||||
}
|
||||
|
||||
public long recover() {
|
||||
long maxPhysicOffset = -1;
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : this.consumeQueueTable.values()) {
|
||||
for (ConsumeQueueInterface logic : maps.values()) {
|
||||
this.recover(logic);
|
||||
if (logic.getMaxPhysicOffset() > maxPhysicOffset) {
|
||||
maxPhysicOffset = logic.getMaxPhysicOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxPhysicOffset;
|
||||
}
|
||||
|
||||
public void checkSelf(ConsumeQueueInterface consumeQueue) {
|
||||
FileQueueLifeCycle fileQueueLifeCycle = getLifeCycle(consumeQueue.getTopic(), consumeQueue.getQueueId());
|
||||
fileQueueLifeCycle.checkSelf();
|
||||
}
|
||||
|
||||
public void checkSelf() {
|
||||
Iterator<Map.Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>>> it = this.consumeQueueTable.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>> next = it.next();
|
||||
Iterator<Map.Entry<Integer, ConsumeQueueInterface>> itNext = next.getValue().entrySet().iterator();
|
||||
while (itNext.hasNext()) {
|
||||
Map.Entry<Integer, ConsumeQueueInterface> cq = itNext.next();
|
||||
this.checkSelf(cq.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean flush(ConsumeQueueInterface consumeQueue, int flushLeastPages) {
|
||||
FileQueueLifeCycle fileQueueLifeCycle = getLifeCycle(consumeQueue.getTopic(), consumeQueue.getQueueId());
|
||||
return fileQueueLifeCycle.flush(flushLeastPages);
|
||||
@@ -89,9 +233,9 @@ public class ConsumeQueueStore {
|
||||
fileQueueLifeCycle.destroy();
|
||||
}
|
||||
|
||||
public int deleteExpiredFile(ConsumeQueueInterface consumeQueue, long minOffset) {
|
||||
public int deleteExpiredFile(ConsumeQueueInterface consumeQueue, long minCommitLogPos) {
|
||||
FileQueueLifeCycle fileQueueLifeCycle = getLifeCycle(consumeQueue.getTopic(), consumeQueue.getQueueId());
|
||||
return fileQueueLifeCycle.deleteExpiredFile(minOffset);
|
||||
return fileQueueLifeCycle.deleteExpiredFile(minCommitLogPos);
|
||||
}
|
||||
|
||||
public void truncateDirtyLogicFiles(ConsumeQueueInterface consumeQueue, long phyOffset) {
|
||||
@@ -124,10 +268,9 @@ public class ConsumeQueueStore {
|
||||
}
|
||||
|
||||
private ConsumeQueueInterface doFindOrCreateConsumeQueue(String topic, int queueId) {
|
||||
|
||||
ConcurrentMap<Integer, ConsumeQueueInterface> map = consumeQueueTable.get(topic);
|
||||
if (null == map) {
|
||||
ConcurrentMap<Integer, ConsumeQueueInterface> newMap = new ConcurrentHashMap<Integer, ConsumeQueueInterface>(128);
|
||||
ConcurrentMap<Integer, ConsumeQueueInterface> newMap = new ConcurrentHashMap<>(128);
|
||||
ConcurrentMap<Integer, ConsumeQueueInterface> oldMap = consumeQueueTable.putIfAbsent(topic, newMap);
|
||||
if (oldMap != null) {
|
||||
map = oldMap;
|
||||
@@ -143,7 +286,9 @@ public class ConsumeQueueStore {
|
||||
|
||||
ConsumeQueueInterface newLogic;
|
||||
|
||||
if (StoreUtil.isStreamMode(this.messageStore)) {
|
||||
Optional<TopicConfig> topicConfig = this.getTopicConfig(topic);
|
||||
// TODO maybe the topic has been deleted.
|
||||
if (Objects.equals(CQType.BatchCQ, QueueTypeUtils.getCQType(topicConfig))) {
|
||||
newLogic = new BatchConsumeQueue(
|
||||
topic,
|
||||
queueId,
|
||||
@@ -162,7 +307,7 @@ public class ConsumeQueueStore {
|
||||
queueId,
|
||||
StorePathConfigHelper.getStorePathConsumeQueue(this.messageStoreConfig.getStorePathRootDir()),
|
||||
this.messageStoreConfig.getMappedFileSizeConsumeQueue(),
|
||||
(DefaultMessageStore) this.messageStore);
|
||||
this.messageStore);
|
||||
ConsumeQueueInterface oldLogic = map.putIfAbsent(queueId, newLogic);
|
||||
if (oldLogic != null) {
|
||||
logic = oldLogic;
|
||||
@@ -173,4 +318,129 @@ public class ConsumeQueueStore {
|
||||
|
||||
return logic;
|
||||
}
|
||||
|
||||
public Long getMaxOffset(String topic, int queueId) {
|
||||
return this.queueOffsetAssigner.getTopicQueueTable().get(topic + "-" + queueId);
|
||||
}
|
||||
|
||||
public void setTopicQueueTable(HashMap<String, Long> topicQueueTable) {
|
||||
this.queueOffsetAssigner.setTopicQueueTable(topicQueueTable);
|
||||
}
|
||||
|
||||
public void setBatchTopicQueueTable(HashMap<String, Long> batchTopicQueueTable) {
|
||||
this.queueOffsetAssigner.setBatchTopicQueueTable(batchTopicQueueTable);
|
||||
}
|
||||
|
||||
public void assignQueueOffset(MessageExtBrokerInner msg, short messageNum) {
|
||||
FileQueueLifeCycle fileQueueLifeCycle = getLifeCycle(msg.getTopic(), msg.getQueueId());
|
||||
fileQueueLifeCycle.assignQueueOffset(this.queueOffsetAssigner, msg, messageNum);
|
||||
}
|
||||
|
||||
public void removeTopicQueueTable(String topic, Integer queueId) {
|
||||
this.queueOffsetAssigner.remove(topic, queueId);
|
||||
}
|
||||
|
||||
public ConcurrentMap<String, ConcurrentMap<Integer, ConsumeQueueInterface>> getConsumeQueueTable() {
|
||||
return consumeQueueTable;
|
||||
}
|
||||
|
||||
private void putConsumeQueue(final String topic, final int queueId, final ConsumeQueueInterface consumeQueue) {
|
||||
ConcurrentMap<Integer/* queueId */, ConsumeQueueInterface> map = this.consumeQueueTable.get(topic);
|
||||
if (null == map) {
|
||||
map = new ConcurrentHashMap<>();
|
||||
map.put(queueId, consumeQueue);
|
||||
this.consumeQueueTable.put(topic, map);
|
||||
} else {
|
||||
map.put(queueId, consumeQueue);
|
||||
}
|
||||
}
|
||||
|
||||
public void recoverOffsetTable(long minPhyOffset) {
|
||||
HashMap<String, Long> cqOffsetTable = new HashMap<>(1024);
|
||||
HashMap<String, Long> bcqOffsetTable = new HashMap<>(1024);
|
||||
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : this.consumeQueueTable.values()) {
|
||||
for (ConsumeQueueInterface logic : maps.values()) {
|
||||
String key = logic.getTopic() + "-" + logic.getQueueId();
|
||||
|
||||
long maxOffsetInQueue = logic.getMaxOffsetInQueue();
|
||||
if (Objects.equals(CQType.BatchCQ, logic.getCQType())) {
|
||||
bcqOffsetTable.put(key, maxOffsetInQueue);
|
||||
} else {
|
||||
cqOffsetTable.put(key, maxOffsetInQueue);
|
||||
}
|
||||
|
||||
this.correctMinOffset(logic, minPhyOffset);
|
||||
}
|
||||
}
|
||||
|
||||
this.setTopicQueueTable(cqOffsetTable);
|
||||
this.setBatchTopicQueueTable(bcqOffsetTable);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : this.consumeQueueTable.values()) {
|
||||
for (ConsumeQueueInterface logic : maps.values()) {
|
||||
this.destroy(logic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanExpired(long minCommitLogOffset) {
|
||||
Iterator<Map.Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>>> it = this.consumeQueueTable.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<String, ConcurrentMap<Integer, ConsumeQueueInterface>> next = it.next();
|
||||
String topic = next.getKey();
|
||||
if (!topic.equals(TopicValidator.RMQ_SYS_SCHEDULE_TOPIC)) {
|
||||
ConcurrentMap<Integer, ConsumeQueueInterface> queueTable = next.getValue();
|
||||
Iterator<Map.Entry<Integer, ConsumeQueueInterface>> itQT = queueTable.entrySet().iterator();
|
||||
while (itQT.hasNext()) {
|
||||
Map.Entry<Integer, ConsumeQueueInterface> nextQT = itQT.next();
|
||||
long maxCLOffsetInConsumeQueue = nextQT.getValue().getLastOffset();
|
||||
|
||||
if (maxCLOffsetInConsumeQueue == -1) {
|
||||
log.warn("maybe ConsumeQueue was created just now. topic={} queueId={} maxPhysicOffset={} minLogicOffset={}.",
|
||||
nextQT.getValue().getTopic(),
|
||||
nextQT.getValue().getQueueId(),
|
||||
nextQT.getValue().getMaxPhysicOffset(),
|
||||
nextQT.getValue().getMinLogicOffset());
|
||||
} else if (maxCLOffsetInConsumeQueue < minCommitLogOffset) {
|
||||
log.info(
|
||||
"cleanExpiredConsumerQueue: {} {} consumer queue destroyed, minCommitLogOffset: {} maxCLOffsetInConsumeQueue: {}",
|
||||
topic,
|
||||
nextQT.getKey(),
|
||||
minCommitLogOffset,
|
||||
maxCLOffsetInConsumeQueue);
|
||||
|
||||
removeTopicQueueTable(nextQT.getValue().getTopic(),
|
||||
nextQT.getValue().getQueueId());
|
||||
|
||||
this.destroy(nextQT.getValue());
|
||||
itQT.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (queueTable.isEmpty()) {
|
||||
log.info("cleanExpiredConsumerQueue: {},topic destroyed", topic);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void truncateDirty(long phyOffset) {
|
||||
for (ConcurrentMap<Integer, ConsumeQueueInterface> maps : this.consumeQueueTable.values()) {
|
||||
for (ConsumeQueueInterface logic : maps.values()) {
|
||||
this.truncateDirtyLogicFiles(logic, phyOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<TopicConfig> getTopicConfig(String topic) {
|
||||
if (this.topicConfigTable == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.ofNullable(this.topicConfigTable.get(topic));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.apache.rocketmq.store.queue;
|
||||
|
||||
import org.apache.rocketmq.store.DispatchRequest;
|
||||
import org.apache.rocketmq.store.MessageExtBrokerInner;
|
||||
import org.apache.rocketmq.store.Swappable;
|
||||
|
||||
public interface FileQueueLifeCycle extends Swappable {
|
||||
@@ -32,4 +33,5 @@ public interface FileQueueLifeCycle extends Swappable {
|
||||
boolean isFirstFileExist();
|
||||
void correctMinOffset(long minCommitLogOffset);
|
||||
void putMessagePositionInfoWrapper(DispatchRequest request);
|
||||
void assignQueueOffset(QueueOffsetAssigner queueOffsetAssigner, MessageExtBrokerInner msg, short messageNum);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.rocketmq.store.queue;
|
||||
|
||||
import org.apache.rocketmq.common.constant.LoggerName;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* QueueOffsetAssigner is a component for assigning queue.
|
||||
*
|
||||
*/
|
||||
public class QueueOffsetAssigner {
|
||||
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.STORE_LOGGER_NAME);
|
||||
|
||||
private HashMap<String, Long> topicQueueTable = new HashMap<>(1024);
|
||||
private HashMap<String, Long> batchTopicQueueTable = new HashMap<>(1024);
|
||||
|
||||
public HashMap<String, Long> getTopicQueueTable() {
|
||||
return topicQueueTable;
|
||||
}
|
||||
|
||||
public void setTopicQueueTable(HashMap<String, Long> topicQueueTable) {
|
||||
this.topicQueueTable = topicQueueTable;
|
||||
}
|
||||
|
||||
public HashMap<String, Long> getBatchTopicQueueTable() {
|
||||
return batchTopicQueueTable;
|
||||
}
|
||||
|
||||
public void setBatchTopicQueueTable(HashMap<String, Long> batchTopicQueueTable) {
|
||||
this.batchTopicQueueTable = batchTopicQueueTable;
|
||||
}
|
||||
|
||||
public synchronized void remove(String topic, Integer queueId) {
|
||||
String topicQueueKey = topic + "-" + queueId;
|
||||
// Beware of thread-safety
|
||||
this.topicQueueTable.remove(topicQueueKey);
|
||||
this.batchTopicQueueTable.remove(topicQueueKey);
|
||||
|
||||
log.info("removeQueueFromTopicQueueTable OK Topic: {} QueueId: {}", topic, queueId);
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.store.util;
|
||||
|
||||
import org.apache.rocketmq.common.TopicAttributes;
|
||||
import org.apache.rocketmq.common.TopicConfig;
|
||||
import org.apache.rocketmq.store.DefaultMessageStore;
|
||||
import org.apache.rocketmq.store.MessageStore;
|
||||
import org.apache.rocketmq.store.StreamMessageStore;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class QueueTypeUtils {
|
||||
|
||||
@Deprecated
|
||||
public static CQType getCQType(MessageStore messageStore) {
|
||||
if (messageStore instanceof DefaultMessageStore) {
|
||||
return CQType.SimpleCQ;
|
||||
} else if (messageStore instanceof StreamMessageStore) {
|
||||
return CQType.BatchCQ;
|
||||
} else {
|
||||
throw new RuntimeException("new cq type is not supported now.");
|
||||
}
|
||||
}
|
||||
|
||||
public static CQType getCQType(TopicConfig topicConfig) {
|
||||
String attributeName = TopicAttributes.QUEUE_TYPE.getName();
|
||||
|
||||
Map<String, String> attributes = topicConfig.getAttributes();
|
||||
if (attributes == null || attributes.size() == 0) {
|
||||
return CQType.valueOf(TopicAttributes.QUEUE_TYPE.getDefaultValue());
|
||||
}
|
||||
|
||||
if (attributes.containsKey(attributeName)) {
|
||||
return CQType.valueOf(attributes.get(attributeName));
|
||||
} else {
|
||||
return CQType.valueOf(TopicAttributes.QUEUE_TYPE.getDefaultValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import org.apache.rocketmq.common.UtilAll;
|
||||
import org.apache.rocketmq.store.config.FlushDiskType;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
import org.apache.rocketmq.store.config.StorePathConfigHelper;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.store.stats.BrokerStatsManager;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -72,7 +72,6 @@ public class DefaultMessageStoreShutDownTest {
|
||||
messageStoreConfig.setMaxIndexNum(100 * 100);
|
||||
messageStoreConfig.setFlushDiskType(FlushDiskType.SYNC_FLUSH);
|
||||
messageStoreConfig.setHaListenPort(StoreTestBase.nextPort());
|
||||
messageStoreConfig.setDefaultCQType(CQType.SimpleCQ.name());
|
||||
return new DefaultMessageStore(messageStoreConfig, new BrokerStatsManager("simpleTest"), null, new BrokerConfig());
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ import org.apache.rocketmq.store.config.FlushDiskType;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
import org.apache.rocketmq.store.config.StorePathConfigHelper;
|
||||
import org.apache.rocketmq.store.logfile.DefaultMappedFile;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.store.queue.ConsumeQueueInterface;
|
||||
import org.apache.rocketmq.store.queue.CqUnit;
|
||||
import org.apache.rocketmq.store.stats.BrokerStatsManager;
|
||||
@@ -115,7 +115,6 @@ public class DefaultMessageStoreTest {
|
||||
messageStoreConfig.setFlushDiskType(FlushDiskType.SYNC_FLUSH);
|
||||
messageStoreConfig.setFlushIntervalConsumeQueue(1);
|
||||
messageStoreConfig.setHaListenPort(StoreTestBase.nextPort());
|
||||
messageStoreConfig.setDefaultCQType(CQType.SimpleCQ.name());
|
||||
return new DefaultMessageStore(messageStoreConfig, new BrokerStatsManager("simpleTest"), new MyMessageArrivingListener(), new BrokerConfig());
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,17 @@
|
||||
|
||||
package org.apache.rocketmq.store.queue;
|
||||
|
||||
import org.apache.rocketmq.common.TopicAttributes;
|
||||
import org.apache.rocketmq.common.TopicConfig;
|
||||
import org.apache.rocketmq.common.UtilAll;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.common.message.MessageAccessor;
|
||||
import org.apache.rocketmq.common.message.MessageConst;
|
||||
import org.apache.rocketmq.common.message.MessageDecoder;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
|
||||
import org.apache.rocketmq.common.utils.QueueTypeUtils;
|
||||
import org.apache.rocketmq.store.DefaultMessageStore;
|
||||
import org.apache.rocketmq.store.GetMessageResult;
|
||||
import org.apache.rocketmq.store.GetMessageStatus;
|
||||
import org.apache.rocketmq.store.MessageExtBrokerInner;
|
||||
@@ -27,21 +35,168 @@ import org.apache.rocketmq.store.MessageStore;
|
||||
import org.apache.rocketmq.store.PutMessageResult;
|
||||
import org.apache.rocketmq.store.PutMessageStatus;
|
||||
import org.apache.rocketmq.store.SelectMappedBufferResult;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
|
||||
public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
private MessageStore messageStore;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
messageStore = createMessageStore(null, true);
|
||||
messageStore.load();
|
||||
messageStore.start();
|
||||
}
|
||||
|
||||
@After
|
||||
public void destroy() {
|
||||
messageStore.shutdown();
|
||||
messageStore.destroy();
|
||||
|
||||
File file = new File(messageStore.getMessageStoreConfig().getStorePathRootDir());
|
||||
UtilAll.deleteFile(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendMessagesToCqTopic() {
|
||||
String topic = UUID.randomUUID().toString();
|
||||
createTopic(topic, CQType.SimpleCQ, messageStore);
|
||||
|
||||
int batchNum = 10;
|
||||
|
||||
// case 1 has PROPERTY_INNER_NUM but has no INNER_BATCH_FLAG
|
||||
MessageExtBrokerInner messageExtBrokerInner = buildMessage(topic, batchNum);
|
||||
messageExtBrokerInner.setSysFlag(0);
|
||||
PutMessageResult putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
Assert.assertEquals(PutMessageStatus.MESSAGE_ILLEGAL, putMessageResult.getPutMessageStatus());
|
||||
|
||||
// case 2 has PROPERTY_INNER_NUM and has INNER_BATCH_FLAG, but is not a batchCq
|
||||
messageExtBrokerInner = buildMessage(topic, 1);
|
||||
putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
Assert.assertEquals(PutMessageStatus.MESSAGE_ILLEGAL, putMessageResult.getPutMessageStatus());
|
||||
|
||||
// case 3 has neither PROPERTY_INNER_NUM nor INNER_BATCH_FLAG.
|
||||
messageExtBrokerInner = buildMessage(topic, -1);
|
||||
putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
Assert.assertEquals(PutMessageStatus.PUT_OK, putMessageResult.getPutMessageStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendMessagesToBcqTopic() {
|
||||
String topic = UUID.randomUUID().toString();
|
||||
createTopic(topic, CQType.BatchCQ, messageStore);
|
||||
|
||||
// case 1 has PROPERTY_INNER_NUM but has no INNER_BATCH_FLAG
|
||||
MessageExtBrokerInner messageExtBrokerInner = buildMessage(topic, 1);
|
||||
PutMessageResult putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
Assert.assertEquals(PutMessageStatus.MESSAGE_ILLEGAL, putMessageResult.getPutMessageStatus());
|
||||
|
||||
// case 2 has neither PROPERTY_INNER_NUM nor INNER_BATCH_FLAG.
|
||||
messageExtBrokerInner = buildMessage(topic, -1);
|
||||
putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
Assert.assertEquals(PutMessageStatus.PUT_OK, putMessageResult.getPutMessageStatus());
|
||||
|
||||
// case 3 has INNER_BATCH_FLAG but has no PROPERTY_INNER_NUM.
|
||||
messageExtBrokerInner = buildMessage(topic, 1);
|
||||
MessageAccessor.clearProperty(messageExtBrokerInner, MessageConst.PROPERTY_INNER_NUM);
|
||||
messageExtBrokerInner.setSysFlag(MessageSysFlag.INNER_BATCH_FLAG);
|
||||
putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
Assert.assertEquals(PutMessageStatus.PUT_OK, putMessageResult.getPutMessageStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumeBatchMessage() {
|
||||
String topic = UUID.randomUUID().toString();
|
||||
createTopic(topic, CQType.BatchCQ, messageStore);
|
||||
int batchNum = 10;
|
||||
|
||||
MessageExtBrokerInner messageExtBrokerInner = buildMessage(topic, batchNum);
|
||||
PutMessageResult putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
Assert.assertEquals(PutMessageStatus.PUT_OK, putMessageResult.getPutMessageStatus());
|
||||
|
||||
await().atMost(5, SECONDS).until(fullyDispatched(messageStore));
|
||||
|
||||
List<GetMessageResult> results = new ArrayList<>();
|
||||
for (int i = 0; i < batchNum; i++) {
|
||||
GetMessageResult result = messageStore.getMessage("whatever", topic, 0, i, Integer.MAX_VALUE, Integer.MAX_VALUE, null);
|
||||
try {
|
||||
Assert.assertEquals(GetMessageStatus.FOUND, result.getStatus());
|
||||
results.add(result);
|
||||
} finally {
|
||||
result.release();
|
||||
}
|
||||
}
|
||||
|
||||
for (GetMessageResult result : results) {
|
||||
Assert.assertEquals(0, result.getMinOffset());
|
||||
Assert.assertEquals(batchNum, result.getMaxOffset());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextBeginOffsetConsumeBatchMessage() {
|
||||
String topic = UUID.randomUUID().toString();
|
||||
createTopic(topic, CQType.BatchCQ, messageStore);
|
||||
Random random = new Random();
|
||||
int putMessageCount = 1000;
|
||||
|
||||
Queue<Integer> queue = new ArrayDeque<>();
|
||||
for (int i = 0; i < putMessageCount; i++) {
|
||||
int batchNum = random.nextInt(1000) + 2;
|
||||
MessageExtBrokerInner messageExtBrokerInner = buildMessage(topic, batchNum);
|
||||
PutMessageResult putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
Assert.assertEquals(PutMessageStatus.PUT_OK, putMessageResult.getPutMessageStatus());
|
||||
queue.add(batchNum);
|
||||
}
|
||||
|
||||
await().atMost(5, SECONDS).until(fullyDispatched(messageStore));
|
||||
|
||||
long pullOffset = 0L;
|
||||
int getMessageCount = 0;
|
||||
while (true) {
|
||||
GetMessageResult getMessageResult = messageStore.getMessage("group", topic, 0, pullOffset, 1, null);
|
||||
if (Objects.equals(getMessageResult.getStatus(), GetMessageStatus.OFFSET_OVERFLOW_ONE)) {
|
||||
break;
|
||||
}
|
||||
Assert.assertEquals(1, getMessageResult.getMessageQueueOffset().size());
|
||||
Long baseOffset = getMessageResult.getMessageQueueOffset().get(0);
|
||||
Integer batchNum = queue.poll();
|
||||
Assert.assertNotNull(batchNum);
|
||||
Assert.assertEquals(baseOffset + batchNum, getMessageResult.getNextBeginOffset());
|
||||
pullOffset = getMessageResult.getNextBeginOffset();
|
||||
getMessageCount++;
|
||||
}
|
||||
Assert.assertEquals(putMessageCount, getMessageCount);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffsetInQueueByTime() throws Exception {
|
||||
MessageStore messageStore = createMessageStore(null, true, CQType.BatchCQ);
|
||||
messageStore.load();
|
||||
messageStore.start();
|
||||
String topic = "testGetOffsetInQueueByTime";
|
||||
|
||||
//The initial min max offset, before and after the creation of consume queue
|
||||
createTopic(topic, CQType.BatchCQ, messageStore);
|
||||
Assert.assertTrue(QueueTypeUtils.isBatchCq(messageStore.getTopicConfig(topic)));
|
||||
|
||||
// The initial min max offset, before and after the creation of consume queue
|
||||
Assert.assertEquals(0, messageStore.getMaxOffsetInQueue(topic, 0));
|
||||
Assert.assertEquals(-1, messageStore.getMinOffsetInQueue(topic, 0));
|
||||
|
||||
@@ -54,34 +209,30 @@ public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
if (i == 7)
|
||||
timeMid = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
await().atMost(5, SECONDS).until(fullyDispatched(messageStore));
|
||||
|
||||
Assert.assertEquals(80, messageStore.getOffsetInQueueByTime(topic, 0, timeMid));
|
||||
Assert.assertEquals(0, messageStore.getMinOffsetInQueue(topic, 0));
|
||||
Assert.assertEquals(190, messageStore.getMaxOffsetInQueue(topic, 0));
|
||||
|
||||
Thread.sleep(5 * 1000);
|
||||
int maxBatchDeleteFilesNum = messageStore.getMessageStoreConfig().getMaxBatchDeleteFilesNum();
|
||||
messageStore.getCommitLog().deleteExpiredFile(1L, 100, 12000, true, maxBatchDeleteFilesNum);
|
||||
Assert.assertEquals(80, messageStore.getOffsetInQueueByTime(topic, 0, timeMid));
|
||||
Thread.sleep(70 * 1000);
|
||||
Assert.assertEquals(180, messageStore.getOffsetInQueueByTime(topic, 0, timeMid));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatchNormalConsumeQueue() throws Exception {
|
||||
MessageStore messageStore = createMessageStore(null, true, CQType.SimpleCQ);
|
||||
messageStore.load();
|
||||
messageStore.start();
|
||||
String topic = "TestDispatchBuildConsumeQueue";
|
||||
int batchNum = 10;
|
||||
createTopic(topic, CQType.SimpleCQ, messageStore);
|
||||
|
||||
long timeStart = System.currentTimeMillis();
|
||||
long timeMid = -1;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
// MessageExtBrokerInner messageExtBrokerInner = buildMessage(topic, batchNum);
|
||||
// messageExtBrokerInner.setSysFlag(0);
|
||||
// PutMessageResult putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
// Assert.assertEquals(PutMessageStatus.MESSAGE_ILLEGAL, putMessageResult.getPutMessageStatus());
|
||||
//
|
||||
// messageExtBrokerInner = buildMessage(topic, 1);
|
||||
// putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
// Assert.assertEquals(PutMessageStatus.MESSAGE_ILLEGAL, putMessageResult.getPutMessageStatus());
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
MessageExtBrokerInner messageExtBrokerInner = buildMessage(topic, -1);
|
||||
PutMessageResult putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
Assert.assertEquals(PutMessageStatus.PUT_OK, putMessageResult.getPutMessageStatus());
|
||||
@@ -90,7 +241,9 @@ public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
if (i == 49)
|
||||
timeMid = System.currentTimeMillis();
|
||||
}
|
||||
Thread.sleep(500);
|
||||
|
||||
await().atMost(5, SECONDS).until(fullyDispatched(messageStore));
|
||||
|
||||
ConsumeQueueInterface consumeQueue = messageStore.getConsumeQueue(topic, 0);
|
||||
Assert.assertEquals(CQType.SimpleCQ, consumeQueue.getCQType());
|
||||
//check the consume queue
|
||||
@@ -106,43 +259,41 @@ public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
for (int i = -100; i < 100; i += 20) {
|
||||
Assert.assertEquals(consumeQueue.getOffsetInQueueByTime(timeMid + i), messageStore.getOffsetInQueueByTime(topic, 0, timeMid + i));
|
||||
}
|
||||
|
||||
//check the message time
|
||||
long latencyAllowed = 20;
|
||||
long earlistMessageTime = messageStore.getEarliestMessageTime(topic, 0);
|
||||
Assert.assertTrue(earlistMessageTime > timeStart - 10);
|
||||
Assert.assertTrue(earlistMessageTime < timeStart + 10);
|
||||
Assert.assertTrue(earlistMessageTime > timeStart - latencyAllowed);
|
||||
Assert.assertTrue(earlistMessageTime < timeStart + latencyAllowed);
|
||||
long messageStoreTime = messageStore.getMessageStoreTimeStamp(topic, 0, 50);
|
||||
Assert.assertTrue(messageStoreTime > timeMid - 10);
|
||||
Assert.assertTrue(messageStoreTime < timeMid + 10);
|
||||
Assert.assertTrue(messageStoreTime > timeMid - latencyAllowed);
|
||||
Assert.assertTrue(messageStoreTime < timeMid + latencyAllowed);
|
||||
long commitLogOffset = messageStore.getCommitLogOffsetInQueue(topic, 0, 50);
|
||||
Assert.assertTrue(commitLogOffset >= messageStore.getMinPhyOffset());
|
||||
Assert.assertTrue(commitLogOffset <= messageStore.getMaxPhyOffset());
|
||||
|
||||
Assert.assertFalse(messageStore.checkInDiskByConsumeOffset(topic, 0, 50));
|
||||
messageStore.shutdown();
|
||||
messageStore.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatchBuildBatchConsumeQueue() throws Exception {
|
||||
MessageStore messageStore = createMessageStore(null, true, CQType.BatchCQ);
|
||||
messageStore.load();
|
||||
messageStore.start();
|
||||
String topic = "testDispatchBuildBatchConsumeQueue";
|
||||
int batchNum = 10;
|
||||
long timeStart = System.currentTimeMillis();
|
||||
long timeMid = -1;
|
||||
|
||||
createTopic(topic, CQType.BatchCQ, messageStore);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
PutMessageResult putMessageResult = messageStore.putMessage(buildMessage(topic, batchNum));
|
||||
Assert.assertEquals(PutMessageStatus.PUT_OK, putMessageResult.getPutMessageStatus());
|
||||
Thread.sleep(2);
|
||||
if (i == 29)
|
||||
timeMid = System.currentTimeMillis();
|
||||
|
||||
MessageExtBrokerInner messageExtBrokerInner = buildMessage(topic, 1);
|
||||
putMessageResult = messageStore.putMessage(messageExtBrokerInner);
|
||||
Assert.assertEquals(PutMessageStatus.MESSAGE_ILLEGAL, putMessageResult.getPutMessageStatus());
|
||||
}
|
||||
Thread.sleep(500);
|
||||
|
||||
await().atMost(5, SECONDS).until(fullyDispatched(messageStore));
|
||||
|
||||
ConsumeQueueInterface consumeQueue = messageStore.getConsumeQueue(topic, 0);
|
||||
Assert.assertEquals(CQType.BatchCQ, consumeQueue.getCQType());
|
||||
|
||||
@@ -176,21 +327,18 @@ public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
SelectMappedBufferResult sbr = getMessageResult.getMessageMapedList().get(i);
|
||||
MessageExt messageExt = MessageDecoder.decode(sbr.getByteBuffer());
|
||||
short tmpBatchNum = Short.valueOf(messageExt.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
short tmpBatchNum = Short.parseShort(messageExt.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
Assert.assertEquals(i * batchNum, Long.parseLong(messageExt.getProperty(MessageConst.PROPERTY_INNER_BASE)));
|
||||
Assert.assertEquals(batchNum, tmpBatchNum);
|
||||
}
|
||||
|
||||
messageStore.destroy();
|
||||
messageStore.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBatchMessageWithinNumber() throws Exception {
|
||||
MessageStore messageStore = createMessageStore(null, true, CQType.BatchCQ);
|
||||
messageStore.load();
|
||||
messageStore.start();
|
||||
public void testGetBatchMessageWithinNumber() {
|
||||
String topic = UUID.randomUUID().toString();
|
||||
|
||||
createTopic(topic, CQType.BatchCQ, messageStore);
|
||||
|
||||
int batchNum = 20;
|
||||
for (int i = 0; i < 200; i++) {
|
||||
PutMessageResult putMessageResult = messageStore.putMessage(buildMessage(topic, batchNum));
|
||||
@@ -198,7 +346,9 @@ public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
Assert.assertEquals(i * batchNum, putMessageResult.getAppendMessageResult().getLogicsOffset());
|
||||
Assert.assertEquals(batchNum, putMessageResult.getAppendMessageResult().getMsgNum());
|
||||
}
|
||||
Thread.sleep(500);
|
||||
|
||||
await().atMost(5, SECONDS).until(fullyDispatched(messageStore));
|
||||
|
||||
ConsumeQueueInterface consumeQueue = messageStore.getConsumeQueue(topic, 0);
|
||||
Assert.assertEquals(CQType.BatchCQ, consumeQueue.getCQType());
|
||||
Assert.assertEquals(0, consumeQueue.getMinOffsetInQueue());
|
||||
@@ -212,7 +362,7 @@ public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
Assert.assertEquals(batchNum, getMessageResult.getMessageCount());
|
||||
SelectMappedBufferResult sbr = getMessageResult.getMessageMapedList().get(0);
|
||||
MessageExt messageExt = MessageDecoder.decode(sbr.getByteBuffer());
|
||||
short tmpBatchNum = Short.valueOf(messageExt.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
short tmpBatchNum = Short.parseShort(messageExt.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
Assert.assertEquals(0, messageExt.getQueueOffset());
|
||||
Assert.assertEquals(batchNum, tmpBatchNum);
|
||||
}
|
||||
@@ -236,22 +386,19 @@ public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
SelectMappedBufferResult sbr = getMessageResult.getMessageMapedList().get(i);
|
||||
MessageExt messageExt = MessageDecoder.decode(sbr.getByteBuffer());
|
||||
Assert.assertNotNull(messageExt);
|
||||
short innerBatchNum = Short.valueOf(messageExt.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
short innerBatchNum = Short.parseShort(messageExt.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
Assert.assertEquals(i * batchNum, Long.parseLong(messageExt.getProperty(MessageConst.PROPERTY_INNER_BASE)));
|
||||
Assert.assertEquals(batchNum, innerBatchNum);
|
||||
|
||||
}
|
||||
}
|
||||
messageStore.destroy();
|
||||
messageStore.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBatchMessageWithinSize() throws Exception {
|
||||
MessageStore messageStore = createMessageStore(null, true, CQType.BatchCQ);
|
||||
messageStore.load();
|
||||
messageStore.start();
|
||||
public void testGetBatchMessageWithinSize() {
|
||||
String topic = UUID.randomUUID().toString();
|
||||
createTopic(topic, CQType.BatchCQ, messageStore);
|
||||
|
||||
int batchNum = 10;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
PutMessageResult putMessageResult = messageStore.putMessage(buildMessage(topic, batchNum));
|
||||
@@ -259,7 +406,9 @@ public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
Assert.assertEquals(i * 10, putMessageResult.getAppendMessageResult().getLogicsOffset());
|
||||
Assert.assertEquals(batchNum, putMessageResult.getAppendMessageResult().getMsgNum());
|
||||
}
|
||||
Thread.sleep(500);
|
||||
|
||||
await().atMost(5, SECONDS).until(fullyDispatched(messageStore));
|
||||
|
||||
ConsumeQueueInterface consumeQueue = messageStore.getConsumeQueue(topic, 0);
|
||||
Assert.assertEquals(CQType.BatchCQ, consumeQueue.getCQType());
|
||||
Assert.assertEquals(0, consumeQueue.getMinOffsetInQueue());
|
||||
@@ -272,7 +421,7 @@ public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
Assert.assertEquals(1, getMessageResult.getMessageMapedList().size());
|
||||
SelectMappedBufferResult sbr = getMessageResult.getMessageMapedList().get(0);
|
||||
MessageExt messageExt = MessageDecoder.decode(sbr.getByteBuffer());
|
||||
short tmpBatchNum = Short.valueOf(messageExt.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
short tmpBatchNum = Short.parseShort(messageExt.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
Assert.assertEquals(0, messageExt.getQueueOffset());
|
||||
Assert.assertEquals(batchNum, tmpBatchNum);
|
||||
}
|
||||
@@ -293,14 +442,29 @@ public class BatchConsumeMessageTest extends QueueTestBase {
|
||||
Assert.assertFalse(getMessageResult.getMessageMapedList().get(i).hasReleased());
|
||||
SelectMappedBufferResult sbr = getMessageResult.getMessageMapedList().get(i);
|
||||
MessageExt messageExt = MessageDecoder.decode(sbr.getByteBuffer());
|
||||
short tmpBatchNum = Short.valueOf(messageExt.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
short tmpBatchNum = Short.parseShort(messageExt.getProperty(MessageConst.PROPERTY_INNER_NUM));
|
||||
Assert.assertEquals(i * batchNum, Long.parseLong(messageExt.getProperty(MessageConst.PROPERTY_INNER_BASE)));
|
||||
Assert.assertEquals(batchNum, tmpBatchNum);
|
||||
|
||||
}
|
||||
}
|
||||
messageStore.destroy();
|
||||
messageStore.shutdown();
|
||||
}
|
||||
|
||||
private void createTopic(String topic, CQType cqType, MessageStore messageStore) {
|
||||
ConcurrentMap<String, TopicConfig> topicConfigTable = new ConcurrentHashMap<>();
|
||||
TopicConfig topicConfigToBeAdded = new TopicConfig();
|
||||
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put(TopicAttributes.QUEUE_TYPE_ATTRIBUTE.getName(), cqType.toString());
|
||||
topicConfigToBeAdded.setTopicName(topic);
|
||||
topicConfigToBeAdded.setAttributes(attributes);
|
||||
|
||||
topicConfigTable.put(topic, topicConfigToBeAdded);
|
||||
((DefaultMessageStore)messageStore).setTopicConfigTable(topicConfigTable);
|
||||
}
|
||||
|
||||
private Callable<Boolean> fullyDispatched(MessageStore messageStore) {
|
||||
return () -> messageStore.dispatchBehindBytes() == 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ package org.apache.rocketmq.store.queue;
|
||||
|
||||
import org.apache.rocketmq.common.BrokerConfig;
|
||||
import org.apache.rocketmq.store.ConsumeQueue;
|
||||
import org.apache.rocketmq.store.StreamMessageStore;
|
||||
import org.apache.rocketmq.store.MessageArrivingListener;
|
||||
import org.apache.rocketmq.store.DefaultMessageStore;
|
||||
import org.apache.rocketmq.store.MessageStore;
|
||||
import org.apache.rocketmq.store.SelectMappedBufferResult;
|
||||
import org.apache.rocketmq.store.StoreTestBase;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
@@ -32,7 +32,6 @@ import org.junit.Test;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import static java.lang.String.format;
|
||||
@@ -45,13 +44,13 @@ public class BatchConsumeQueueTest extends StoreTestBase {
|
||||
path = createBaseDir();
|
||||
}
|
||||
baseDirs.add(path);
|
||||
StreamMessageStore bcqMessageStore = null;
|
||||
MessageStore messageStore = null;
|
||||
try {
|
||||
bcqMessageStore = createBcqMessageStore(null);
|
||||
messageStore = createMessageStore(null);
|
||||
} catch (Exception e) {
|
||||
Assert.fail();
|
||||
}
|
||||
BatchConsumeQueue batchConsumeQueue = new BatchConsumeQueue("topic", 0, path,fileSize, bcqMessageStore);
|
||||
BatchConsumeQueue batchConsumeQueue = new BatchConsumeQueue("topic", 0, path,fileSize, messageStore);
|
||||
batchConsumeQueues.add(batchConsumeQueue);
|
||||
return batchConsumeQueue;
|
||||
}
|
||||
@@ -280,7 +279,7 @@ public class BatchConsumeQueueTest extends StoreTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
protected StreamMessageStore createBcqMessageStore(String baseDir) throws Exception {
|
||||
protected MessageStore createMessageStore(String baseDir) throws Exception {
|
||||
if (baseDir == null) {
|
||||
baseDir = createBaseDir();
|
||||
}
|
||||
@@ -299,17 +298,13 @@ public class BatchConsumeQueueTest extends StoreTestBase {
|
||||
messageStoreConfig.setMaxTransferBytesOnMessageInMemory(1024 * 1024);
|
||||
messageStoreConfig.setMaxTransferCountOnMessageInDisk(1024);
|
||||
messageStoreConfig.setMaxTransferCountOnMessageInMemory(1024);
|
||||
messageStoreConfig.setDefaultCQType(CQType.BatchCQ.name());
|
||||
messageStoreConfig.setSearchBcqByCacheEnable(true);
|
||||
|
||||
StreamMessageStore defaultMessageStore = new StreamMessageStore(messageStoreConfig, new BrokerStatsManager("simpleTest"), new MessageArrivingListener() {
|
||||
@Override
|
||||
public void arriving(String topic, int queueId, long logicOffset, long tagsCode, long msgStoreTime,
|
||||
byte[] filterBitMap, Map<String, String> properties) {
|
||||
|
||||
}
|
||||
}, new BrokerConfig());
|
||||
return defaultMessageStore;
|
||||
return new DefaultMessageStore(
|
||||
messageStoreConfig,
|
||||
new BrokerStatsManager("simpleTest"),
|
||||
(topic, queueId, logicOffset, tagsCode, msgStoreTime, filterBitMap, properties) -> {},
|
||||
new BrokerConfig());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package org.apache.rocketmq.store.queue;
|
||||
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.store.ConsumeQueueExt;
|
||||
import org.apache.rocketmq.store.DispatchRequest;
|
||||
import org.apache.rocketmq.store.MessageStore;
|
||||
@@ -30,7 +31,7 @@ public class ConsumeQueueTest extends QueueTestBase {
|
||||
public void testIterator() throws Exception {
|
||||
final int msgNum = 100;
|
||||
final int msgSize = 1000;
|
||||
MessageStore messageStore = createMessageStore(null, true, CQType.SimpleCQ);
|
||||
MessageStore messageStore = createMessageStore(null, true);
|
||||
messageStore.load();
|
||||
String topic = UUID.randomUUID().toString();
|
||||
//The initial min max offset, before and after the creation of consume queue
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.apache.rocketmq.common.message.MessageDecoder;
|
||||
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
|
||||
import org.apache.rocketmq.store.ConsumeQueue;
|
||||
import org.apache.rocketmq.store.DefaultMessageStore;
|
||||
import org.apache.rocketmq.store.StreamMessageStore;
|
||||
import org.apache.rocketmq.store.MessageArrivingListener;
|
||||
import org.apache.rocketmq.store.MessageExtBrokerInner;
|
||||
import org.apache.rocketmq.store.MessageStore;
|
||||
@@ -33,11 +32,10 @@ import org.apache.rocketmq.store.stats.BrokerStatsManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class QueueTestBase extends StoreTestBase {
|
||||
|
||||
protected MessageStore createMessageStore(String baseDir, boolean extent, CQType cqType) throws Exception {
|
||||
protected MessageStore createMessageStore(String baseDir, boolean extent) throws Exception {
|
||||
if (baseDir == null) {
|
||||
baseDir = createBaseDir();
|
||||
}
|
||||
@@ -56,28 +54,18 @@ public class QueueTestBase extends StoreTestBase {
|
||||
messageStoreConfig.setMaxTransferBytesOnMessageInMemory(1024 * 1024);
|
||||
messageStoreConfig.setMaxTransferCountOnMessageInDisk(1024);
|
||||
messageStoreConfig.setMaxTransferCountOnMessageInMemory(1024);
|
||||
messageStoreConfig.setDefaultCQType(cqType.name());
|
||||
|
||||
messageStoreConfig.setFlushIntervalCommitLog(1);
|
||||
messageStoreConfig.setFlushCommitLogThoroughInterval(2);
|
||||
|
||||
if (Objects.equals(CQType.BatchCQ, cqType)) {
|
||||
return new StreamMessageStore(messageStoreConfig, new BrokerStatsManager("simpleTest"), new MessageArrivingListener() {
|
||||
@Override
|
||||
public void arriving(String topic, int queueId, long logicOffset, long tagsCode, long msgStoreTime,
|
||||
byte[] filterBitMap, Map<String, String> properties) {
|
||||
DefaultMessageStore messageStore = new DefaultMessageStore(messageStoreConfig, new BrokerStatsManager("simpleTest"), new MessageArrivingListener() {
|
||||
@Override
|
||||
public void arriving(String topic, int queueId, long logicOffset, long tagsCode, long msgStoreTime,
|
||||
byte[] filterBitMap, Map<String, String> properties) {
|
||||
|
||||
}
|
||||
}, new BrokerConfig());
|
||||
} else {
|
||||
return new DefaultMessageStore(messageStoreConfig, new BrokerStatsManager("simpleTest"), new MessageArrivingListener() {
|
||||
@Override
|
||||
public void arriving(String topic, int queueId, long logicOffset, long tagsCode, long msgStoreTime,
|
||||
byte[] filterBitMap, Map<String, String> properties) {
|
||||
|
||||
}
|
||||
}, new BrokerConfig());
|
||||
}
|
||||
}
|
||||
}, new BrokerConfig());
|
||||
return messageStore;
|
||||
}
|
||||
|
||||
public MessageExtBrokerInner buildMessage(String topic, int batchNum) {
|
||||
|
||||
@@ -50,20 +50,20 @@ public class MQAdminTestUtils {
|
||||
private static Logger log = Logger.getLogger(MQAdminTestUtils.class);
|
||||
|
||||
public static boolean createTopic(String nameSrvAddr, String clusterName, String topic,
|
||||
int queueNum) {
|
||||
int queueNum, Map<String, String> attributes) {
|
||||
int defaultWaitTime = 5;
|
||||
return createTopic(nameSrvAddr, clusterName, topic, queueNum, defaultWaitTime);
|
||||
return createTopic(nameSrvAddr, clusterName, topic, queueNum, attributes, defaultWaitTime);
|
||||
}
|
||||
|
||||
public static boolean createTopic(String nameSrvAddr, String clusterName, String topic,
|
||||
int queueNum, int waitTimeSec) {
|
||||
int queueNum, Map<String, String> attributes, int waitTimeSec) {
|
||||
boolean createResult = false;
|
||||
DefaultMQAdminExt mqAdminExt = new DefaultMQAdminExt();
|
||||
mqAdminExt.setInstanceName(UUID.randomUUID().toString());
|
||||
mqAdminExt.setNamesrvAddr(nameSrvAddr);
|
||||
try {
|
||||
mqAdminExt.start();
|
||||
mqAdminExt.createTopic(clusterName, topic, queueNum);
|
||||
mqAdminExt.createTopic(clusterName, topic, queueNum, attributes);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.apache.rocketmq.common.MQVersion;
|
||||
import org.apache.rocketmq.common.protocol.route.BrokerData;
|
||||
import org.apache.rocketmq.namesrv.NamesrvController;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.test.client.rmq.RMQAsyncSendProducer;
|
||||
import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
|
||||
import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
|
||||
@@ -61,18 +61,14 @@ public class BaseConf {
|
||||
//the logic queue test need at least three brokers
|
||||
protected final static String broker3Name;
|
||||
protected final static String clusterName;
|
||||
protected final static String steamClusterName = "steam-cluster";
|
||||
protected final static int brokerNum;
|
||||
protected final static int waitTime = 5;
|
||||
protected final static int consumeTime = 2 * 60 * 1000;
|
||||
protected final static int QUEUE_NUMBERS = 8;
|
||||
protected final static NamesrvController namesrvController;
|
||||
protected static BrokerController brokerController1;
|
||||
protected static BrokerController brokerController2;
|
||||
protected static BrokerController brokerController3;
|
||||
protected static BrokerController streamBrokerController1;
|
||||
protected static BrokerController streamBrokerController2;
|
||||
protected static BrokerController streamBrokerController3;
|
||||
protected final static BrokerController brokerController1;
|
||||
protected final static BrokerController brokerController2;
|
||||
protected final static BrokerController brokerController3;
|
||||
protected final static List<BrokerController> brokerControllerList;
|
||||
protected final static Map<String, BrokerController> brokerControllerMap;
|
||||
protected final static List<Object> mqClients = new ArrayList<Object>();
|
||||
@@ -80,7 +76,7 @@ public class BaseConf {
|
||||
private final static Logger log = Logger.getLogger(BaseConf.class);
|
||||
|
||||
static {
|
||||
System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, Integer.toString(MQVersion.CURRENT_VERSION));
|
||||
System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, Integer.toString(MQVersion.CURRENT_VERSION));
|
||||
namesrvController = IntegrationTestBase.createAndStartNamesrv();
|
||||
nsAddr = "127.0.0.1:" + namesrvController.getNettyServerConfig().getListenPort();
|
||||
brokerController1 = IntegrationTestBase.createAndStartBroker(nsAddr);
|
||||
@@ -91,9 +87,6 @@ public class BaseConf {
|
||||
broker2Name = brokerController2.getBrokerConfig().getBrokerName();
|
||||
broker3Name = brokerController3.getBrokerConfig().getBrokerName();
|
||||
brokerNum = 3;
|
||||
streamBrokerController1 = IntegrationTestBase.createAndStartBroker(nsAddr, CQType.BatchCQ.toString(), steamClusterName);
|
||||
streamBrokerController2 = IntegrationTestBase.createAndStartBroker(nsAddr, CQType.BatchCQ.toString(), steamClusterName);
|
||||
streamBrokerController3 = IntegrationTestBase.createAndStartBroker(nsAddr, CQType.BatchCQ.toString(), steamClusterName);
|
||||
brokerControllerList = ImmutableList.of(brokerController1, brokerController2, brokerController3);
|
||||
brokerControllerMap = brokerControllerList.stream().collect(Collectors.toMap(input -> input.getBrokerConfig().getBrokerName(), Function.identity()));
|
||||
}
|
||||
@@ -124,7 +117,7 @@ public class BaseConf {
|
||||
|
||||
public static String initTopic() {
|
||||
String topic = "tt-" + MQRandomUtils.getRandomTopic();
|
||||
IntegrationTestBase.initTopic(topic, nsAddr, clusterName);
|
||||
IntegrationTestBase.initTopic(topic, nsAddr, clusterName, CQType.SimpleCQ);
|
||||
|
||||
return topic;
|
||||
}
|
||||
@@ -171,9 +164,9 @@ public class BaseConf {
|
||||
}
|
||||
|
||||
public static RMQNormalProducer getProducer(String nsAddr, String topic, String producerGoup,
|
||||
String instanceName) {
|
||||
String instanceName) {
|
||||
RMQNormalProducer producer = new RMQNormalProducer(nsAddr, topic, producerGoup,
|
||||
instanceName);
|
||||
instanceName);
|
||||
if (debug) {
|
||||
producer.setDebug();
|
||||
}
|
||||
@@ -191,31 +184,31 @@ public class BaseConf {
|
||||
}
|
||||
|
||||
public static RMQNormalConsumer getConsumer(String nsAddr, String topic, String subExpression,
|
||||
AbstractListener listener) {
|
||||
AbstractListener listener) {
|
||||
return getConsumer(nsAddr, topic, subExpression, listener, false);
|
||||
}
|
||||
|
||||
public static RMQNormalConsumer getConsumer(String nsAddr, String topic, String subExpression,
|
||||
AbstractListener listener, boolean useTLS) {
|
||||
AbstractListener listener, boolean useTLS) {
|
||||
String consumerGroup = initConsumerGroup();
|
||||
return getConsumer(nsAddr, consumerGroup, topic, subExpression, listener, useTLS);
|
||||
}
|
||||
|
||||
public static RMQNormalConsumer getConsumer(String nsAddr, String consumerGroup, String topic,
|
||||
String subExpression, AbstractListener listener) {
|
||||
String subExpression, AbstractListener listener) {
|
||||
return getConsumer(nsAddr, consumerGroup, topic, subExpression, listener, false);
|
||||
}
|
||||
|
||||
public static RMQNormalConsumer getConsumer(String nsAddr, String consumerGroup, String topic,
|
||||
String subExpression, AbstractListener listener, boolean useTLS) {
|
||||
String subExpression, AbstractListener listener, boolean useTLS) {
|
||||
RMQNormalConsumer consumer = ConsumerFactory.getRMQNormalConsumer(nsAddr, consumerGroup,
|
||||
topic, subExpression, listener, useTLS);
|
||||
topic, subExpression, listener, useTLS);
|
||||
if (debug) {
|
||||
consumer.setDebug();
|
||||
}
|
||||
mqClients.add(consumer);
|
||||
log.info(String.format("consumer[%s] start,topic[%s],subExpression[%s]", consumerGroup,
|
||||
topic, subExpression));
|
||||
topic, subExpression));
|
||||
return consumer;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,13 +20,18 @@ package org.apache.rocketmq.test.base;
|
||||
import com.google.common.truth.Truth;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.apache.rocketmq.broker.BrokerController;
|
||||
import org.apache.rocketmq.common.BrokerConfig;
|
||||
import org.apache.rocketmq.common.TopicAttributes;
|
||||
import org.apache.rocketmq.common.UtilAll;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.common.namesrv.NamesrvConfig;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
@@ -34,10 +39,8 @@ import org.apache.rocketmq.namesrv.NamesrvController;
|
||||
import org.apache.rocketmq.remoting.netty.NettyClientConfig;
|
||||
import org.apache.rocketmq.remoting.netty.NettyServerConfig;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
import org.apache.rocketmq.test.util.MQAdminTestUtils;
|
||||
import org.apache.rocketmq.test.util.TestUtils;
|
||||
import org.assertj.core.util.Strings;
|
||||
|
||||
public class IntegrationTestBase {
|
||||
public static InternalLogger logger = InternalLoggerFactory.getLogger(IntegrationTestBase.class);
|
||||
@@ -142,34 +145,6 @@ public class IntegrationTestBase {
|
||||
storeConfig.setMaxIndexNum(INDEX_NUM);
|
||||
storeConfig.setMaxHashSlotNum(INDEX_NUM * 4);
|
||||
storeConfig.setDeleteWhen("01;02;03;04;05;06;07;08;09;10;11;12;13;14;15;16;17;18;19;20;21;22;23;00");
|
||||
storeConfig.setDefaultCQType(CQType.SimpleCQ.toString());
|
||||
storeConfig.setMaxTransferCountOnMessageInMemory(1024);
|
||||
storeConfig.setMaxTransferCountOnMessageInDisk(1024);
|
||||
return createAndStartBroker(storeConfig, brokerConfig);
|
||||
}
|
||||
|
||||
public static BrokerController createAndStartBroker(String nsAddr, String cqType, String cluster) {
|
||||
String baseDir = createBaseDir();
|
||||
BrokerConfig brokerConfig = new BrokerConfig();
|
||||
MessageStoreConfig storeConfig = new MessageStoreConfig();
|
||||
brokerConfig.setBrokerName(BROKER_NAME_PREFIX + BROKER_INDEX.incrementAndGet());
|
||||
brokerConfig.setBrokerIP1("127.0.0.1");
|
||||
brokerConfig.setNamesrvAddr(nsAddr);
|
||||
brokerConfig.setEnablePropertyFilter(true);
|
||||
brokerConfig.setLoadBalancePollNameServerInterval(500);
|
||||
brokerConfig.setBrokerClusterName(cluster);
|
||||
storeConfig.setStorePathRootDir(baseDir);
|
||||
storeConfig.setStorePathCommitLog(baseDir + SEP + "commitlog");
|
||||
storeConfig.setMappedFileSizeCommitLog(COMMIT_LOG_SIZE);
|
||||
storeConfig.setMaxIndexNum(INDEX_NUM);
|
||||
storeConfig.setMaxHashSlotNum(INDEX_NUM * 4);
|
||||
storeConfig.setDeleteWhen("01;02;03;04;05;06;07;08;09;10;11;12;13;14;15;16;17;18;19;20;21;22;23;00");
|
||||
|
||||
if (!Strings.isNullOrEmpty(cqType)) {
|
||||
storeConfig.setDefaultCQType(cqType);
|
||||
} else {
|
||||
storeConfig.setDefaultCQType(CQType.SimpleCQ.toString());
|
||||
}
|
||||
storeConfig.setMaxTransferCountOnMessageInMemory(1024);
|
||||
storeConfig.setMaxTransferCountOnMessageInDisk(1024);
|
||||
return createAndStartBroker(storeConfig, brokerConfig);
|
||||
@@ -193,17 +168,21 @@ public class IntegrationTestBase {
|
||||
return brokerController;
|
||||
}
|
||||
|
||||
public static boolean initTopic(String topic, String nsAddr, String clusterName, int queueNumbers) {
|
||||
public static boolean initTopic(String topic, String nsAddr, String clusterName, int queueNumbers, CQType cqType) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
boolean createResult;
|
||||
|
||||
while (true) {
|
||||
createResult = MQAdminTestUtils.createTopic(nsAddr, clusterName, topic, queueNumbers);
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
if (!Objects.equals(CQType.SimpleCQ, cqType)) {
|
||||
attributes.put("+" + TopicAttributes.QUEUE_TYPE_ATTRIBUTE.getName(), cqType.toString());
|
||||
}
|
||||
createResult = MQAdminTestUtils.createTopic(nsAddr, clusterName, topic, queueNumbers, attributes);
|
||||
if (createResult) {
|
||||
break;
|
||||
} else if (System.currentTimeMillis() - startTime > topicCreateTime) {
|
||||
Truth.assertWithMessage(String.format("topic[%s] is created failed after:%d ms", topic,
|
||||
System.currentTimeMillis() - startTime)).fail();
|
||||
System.currentTimeMillis() - startTime)).fail();
|
||||
break;
|
||||
} else {
|
||||
TestUtils.waitForMoment(500);
|
||||
@@ -214,8 +193,8 @@ public class IntegrationTestBase {
|
||||
return createResult;
|
||||
}
|
||||
|
||||
public static boolean initTopic(String topic, String nsAddr, String clusterName) {
|
||||
return initTopic(topic, nsAddr, clusterName, BaseConf.QUEUE_NUMBERS);
|
||||
public static boolean initTopic(String topic, String nsAddr, String clusterName, CQType cqType) {
|
||||
return initTopic(topic, nsAddr, clusterName, BaseConf.QUEUE_NUMBERS, cqType);
|
||||
}
|
||||
|
||||
public static void deleteFile(File file) {
|
||||
|
||||
+2
-3
@@ -30,7 +30,7 @@ import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.common.message.MessageQueue;
|
||||
import org.apache.rocketmq.store.config.BrokerRole;
|
||||
import org.apache.rocketmq.store.config.MessageStoreConfig;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.test.base.BaseConf;
|
||||
import org.apache.rocketmq.test.base.IntegrationTestBase;
|
||||
import org.apache.rocketmq.test.factory.ConsumerFactory;
|
||||
@@ -63,7 +63,6 @@ public class DLedgerProduceAndConsumeIT {
|
||||
storeConfig.setdLegerGroup(brokerName);
|
||||
storeConfig.setdLegerSelfId(selfId);
|
||||
storeConfig.setdLegerPeers(peers);
|
||||
storeConfig.setDefaultCQType(CQType.SimpleCQ.toString());
|
||||
return storeConfig;
|
||||
}
|
||||
|
||||
@@ -83,7 +82,7 @@ public class DLedgerProduceAndConsumeIT {
|
||||
|
||||
String topic = UUID.randomUUID().toString();
|
||||
String consumerGroup = UUID.randomUUID().toString();
|
||||
IntegrationTestBase.initTopic(topic, BaseConf.nsAddr, cluster, 1);
|
||||
IntegrationTestBase.initTopic(topic, BaseConf.nsAddr, cluster, 1, CQType.SimpleCQ);
|
||||
DefaultMQProducer producer = ProducerFactory.getRMQProducer(BaseConf.nsAddr);
|
||||
DefaultMQPullConsumer consumer = ConsumerFactory.getRMQPullConsumer(BaseConf.nsAddr, consumerGroup);
|
||||
|
||||
|
||||
+18
-19
@@ -23,7 +23,6 @@ import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.rocketmq.broker.BrokerController;
|
||||
import org.apache.rocketmq.client.consumer.DefaultMQPullConsumer;
|
||||
import org.apache.rocketmq.client.consumer.PullResult;
|
||||
import org.apache.rocketmq.client.consumer.PullStatus;
|
||||
@@ -32,14 +31,14 @@ import org.apache.rocketmq.client.hook.SendMessageHook;
|
||||
import org.apache.rocketmq.client.producer.DefaultMQProducer;
|
||||
import org.apache.rocketmq.client.producer.SendResult;
|
||||
import org.apache.rocketmq.client.producer.SendStatus;
|
||||
import org.apache.rocketmq.common.TopicAttributes;
|
||||
import org.apache.rocketmq.common.attribute.CQType;
|
||||
import org.apache.rocketmq.common.message.Message;
|
||||
import org.apache.rocketmq.common.message.MessageBatch;
|
||||
import org.apache.rocketmq.common.message.MessageConst;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.apache.rocketmq.common.message.MessageQueue;
|
||||
import org.apache.rocketmq.store.DefaultMessageStore;
|
||||
import org.apache.rocketmq.store.StreamMessageStore;
|
||||
import org.apache.rocketmq.store.queue.CQType;
|
||||
import org.apache.rocketmq.test.base.BaseConf;
|
||||
import org.apache.rocketmq.test.base.IntegrationTestBase;
|
||||
import org.apache.rocketmq.test.client.consumer.tag.TagMessageWith1ConsumerIT;
|
||||
@@ -101,23 +100,23 @@ public class BatchSendIT extends BaseConf {
|
||||
|
||||
@Test
|
||||
public void testBatchSend_SysInnerBatch() throws Exception {
|
||||
waitBrokerRegistered(nsAddr, steamClusterName, brokerNum);
|
||||
|
||||
Assert.assertTrue(streamBrokerController1.getMessageStore() instanceof StreamMessageStore);
|
||||
Assert.assertTrue(streamBrokerController2.getMessageStore() instanceof StreamMessageStore);
|
||||
Assert.assertTrue(streamBrokerController3.getMessageStore() instanceof StreamMessageStore);
|
||||
waitBrokerRegistered(nsAddr, clusterName, brokerNum);
|
||||
|
||||
String batchTopic = UUID.randomUUID().toString();
|
||||
IntegrationTestBase.initTopic(batchTopic, nsAddr, steamClusterName);
|
||||
Assert.assertEquals(8, streamBrokerController1.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getReadQueueNums());
|
||||
Assert.assertEquals(8, streamBrokerController2.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getReadQueueNums());
|
||||
Assert.assertEquals(8, streamBrokerController3.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getReadQueueNums());
|
||||
Assert.assertEquals(-1, streamBrokerController1.getMessageStore().getMinOffsetInQueue(batchTopic, 0));
|
||||
Assert.assertEquals(-1, streamBrokerController2.getMessageStore().getMinOffsetInQueue(batchTopic, 0));
|
||||
Assert.assertEquals(-1, streamBrokerController3.getMessageStore().getMinOffsetInQueue(batchTopic, 0));
|
||||
Assert.assertEquals(0, streamBrokerController1.getMessageStore().getMaxOffsetInQueue(batchTopic, 0));
|
||||
Assert.assertEquals(0, streamBrokerController2.getMessageStore().getMaxOffsetInQueue(batchTopic, 0));
|
||||
Assert.assertEquals(0, streamBrokerController3.getMessageStore().getMaxOffsetInQueue(batchTopic, 0));
|
||||
IntegrationTestBase.initTopic(batchTopic, nsAddr, clusterName, CQType.BatchCQ);
|
||||
|
||||
Assert.assertEquals(CQType.BatchCQ.toString(), brokerController1.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getAttributes().get(TopicAttributes.QUEUE_TYPE_ATTRIBUTE.getName()));
|
||||
Assert.assertEquals(CQType.BatchCQ.toString(), brokerController2.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getAttributes().get(TopicAttributes.QUEUE_TYPE_ATTRIBUTE.getName()));
|
||||
Assert.assertEquals(CQType.BatchCQ.toString(), brokerController3.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getAttributes().get(TopicAttributes.QUEUE_TYPE_ATTRIBUTE.getName()));
|
||||
Assert.assertEquals(8, brokerController1.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getReadQueueNums());
|
||||
Assert.assertEquals(8, brokerController2.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getReadQueueNums());
|
||||
Assert.assertEquals(8, brokerController3.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getReadQueueNums());
|
||||
Assert.assertEquals(-1, brokerController1.getMessageStore().getMinOffsetInQueue(batchTopic, 0));
|
||||
Assert.assertEquals(-1, brokerController2.getMessageStore().getMinOffsetInQueue(batchTopic, 0));
|
||||
Assert.assertEquals(-1, brokerController3.getMessageStore().getMinOffsetInQueue(batchTopic, 0));
|
||||
Assert.assertEquals(0, brokerController1.getMessageStore().getMaxOffsetInQueue(batchTopic, 0));
|
||||
Assert.assertEquals(0, brokerController2.getMessageStore().getMaxOffsetInQueue(batchTopic, 0));
|
||||
Assert.assertEquals(0, brokerController3.getMessageStore().getMaxOffsetInQueue(batchTopic, 0));
|
||||
|
||||
DefaultMQProducer producer = ProducerFactory.getRMQProducer(nsAddr);
|
||||
MessageQueue messageQueue = producer.fetchPublishMessageQueues(batchTopic).iterator().next();
|
||||
@@ -168,7 +167,7 @@ public class BatchSendIT extends BaseConf {
|
||||
Assert.assertTrue(brokerController3.getMessageStore() instanceof DefaultMessageStore);
|
||||
|
||||
String batchTopic = UUID.randomUUID().toString();
|
||||
IntegrationTestBase.initTopic(batchTopic, nsAddr, clusterName);
|
||||
IntegrationTestBase.initTopic(batchTopic, nsAddr, clusterName, CQType.SimpleCQ);
|
||||
Assert.assertEquals(8, brokerController1.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getReadQueueNums());
|
||||
Assert.assertEquals(8, brokerController2.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getReadQueueNums());
|
||||
Assert.assertEquals(8, brokerController3.getTopicConfigManager().getTopicConfigTable().get(batchTopic).getReadQueueNums());
|
||||
|
||||
@@ -95,13 +95,13 @@ public class DefaultMQAdminExt extends ClientConfig implements MQAdminExt {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTopic(String key, String newTopic, int queueNum) throws MQClientException {
|
||||
createTopic(key, newTopic, queueNum, 0);
|
||||
public void createTopic(String key, String newTopic, int queueNum, Map<String, String> attributes) throws MQClientException {
|
||||
createTopic(key, newTopic, queueNum, 0, attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException {
|
||||
defaultMQAdminExtImpl.createTopic(key, newTopic, queueNum, topicSysFlag);
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag, Map<String, String> attributes) throws MQClientException {
|
||||
defaultMQAdminExtImpl.createTopic(key, newTopic, queueNum, topicSysFlag, attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -77,11 +77,8 @@ import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData;
|
||||
import org.apache.rocketmq.common.protocol.route.BrokerData;
|
||||
import org.apache.rocketmq.common.protocol.route.QueueData;
|
||||
import org.apache.rocketmq.common.protocol.route.TopicRouteData;
|
||||
import org.apache.rocketmq.common.statictopic.LogicQueueMappingItem;
|
||||
import org.apache.rocketmq.common.statictopic.TopicConfigAndQueueMapping;
|
||||
import org.apache.rocketmq.common.statictopic.TopicQueueMappingDetail;
|
||||
import org.apache.rocketmq.common.statictopic.TopicQueueMappingOne;
|
||||
import org.apache.rocketmq.common.statictopic.TopicQueueMappingUtils;
|
||||
import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.remoting.RPCHook;
|
||||
@@ -95,9 +92,6 @@ import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
|
||||
import org.apache.rocketmq.tools.admin.api.MessageTrack;
|
||||
import org.apache.rocketmq.tools.admin.api.TrackType;
|
||||
|
||||
import static org.apache.rocketmq.common.statictopic.TopicQueueMappingUtils.checkAndBuildMappingItems;
|
||||
import static org.apache.rocketmq.common.statictopic.TopicQueueMappingUtils.getMappingDetailFromConfig;
|
||||
|
||||
public class DefaultMQAdminExtImpl implements MQAdminExt, MQAdminExtInner {
|
||||
|
||||
private static final Set<String> SYSTEM_GROUP_SET = new HashSet<String>();
|
||||
@@ -1063,13 +1057,13 @@ public class DefaultMQAdminExtImpl implements MQAdminExt, MQAdminExtInner {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTopic(String key, String newTopic, int queueNum) throws MQClientException {
|
||||
createTopic(key, newTopic, queueNum, 0);
|
||||
public void createTopic(String key, String newTopic, int queueNum, Map<String, String> attributes) throws MQClientException {
|
||||
createTopic(key, newTopic, queueNum, 0, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException {
|
||||
this.mqClientInstance.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag);
|
||||
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag, Map<String, String> attributes) throws MQClientException {
|
||||
this.mqClientInstance.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag, attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1176,7 +1170,7 @@ public class DefaultMQAdminExtImpl implements MQAdminExt, MQAdminExtInner {
|
||||
|
||||
@Override
|
||||
public void setMessageRequestMode(final String brokerAddr, final String topic, final String consumerGroup, final
|
||||
MessageRequestMode mode, final int popShareQueueNum, final long timeoutMillis)
|
||||
MessageRequestMode mode, final int popShareQueueNum, final long timeoutMillis)
|
||||
throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException,
|
||||
RemotingConnectException, MQClientException {
|
||||
this.mqClientInstance.getMQClientAPIImpl().setMessageRequestMode(brokerAddr, topic, consumerGroup, mode, popShareQueueNum, timeoutMillis);
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.OptionGroup;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.rocketmq.common.TopicAttributes;
|
||||
import org.apache.rocketmq.common.TopicConfig;
|
||||
import org.apache.rocketmq.common.attribute.AttributeParser;
|
||||
import org.apache.rocketmq.common.sysflag.TopicSysFlag;
|
||||
|
||||
Reference in New Issue
Block a user