RocketMQ自动创建主题机制
相关参数
- autoCreateTopicEnable:用于控制broker是否创建TBW102这个系统主题,4.x默认开启,5.x默认关闭
- defaultTopicQueueNums:自动创建的主题队列数量,默认值为4。该参数控制的是一个broker的数量,如果是集群环境,那么每个broker都会创建4个队列。
当一个3主集群(broker-a、broker-b、broker-c)中每个broker的autoCreateTopicEnable=true、defaultTopicQueueNums=4时,则broker-a、broker-b、broker-c在启动时都会创建一个名为TBW102,队列数为4的主题,合计12个队列。
自动创建主题的过程
自动创建Topic的本质是通过系统主题TBW102的元信息来完成的,详细流程如下。
当生产者发送消息到不存在的Topic OrderTopic时
- 生产者从NameServer中获取该主题的路由信息,此时返回空。
- 生产者查询降级,从NameServer中获取默认主题TBW102的路由信息,若此时还没有,则会报错。
- 拿到TBW102 的路由信息后,便得到了所有的队列信息。
- 生产者从TBW102的队列列表里,按轮询方式(默认行为,取决于send方法)选一个队列(对应某个Broker),把消息发过去。
- 目标Broker收到消息后,发现本地没有
OrderTopic,就会自动创建它:- 该Broker上,
OrderTopic的队列数 = 本机TBW102的队列数,默认由defaultTopicQueueNums控制,通常是 4。 - 然后将
OrderTopic的新路由信息注册到NameServer。
- 该Broker上,
- 生产者之后的请求就能直接从NameServer获取到
OrderTopic的路由,不再依赖TBW102。
坑
从上面这个过程,不难推断出一个重大问题,假设在一个拥有3主的集群(broker-a、broker-b、broker-c),每个broker都开启了autoCreateTopicEnable并且defaultTopicQueueNums=4,意味值TBW102主题拥有12个队列,每个broker都有4个。
当生产者向一个不存在的主题OrderTopic发送一条消息时,生产者从TBW102挑选到一个队列后,假设这个队列位于broker-a上,那么broker-a则会创建OrderTopic主题(包含4个队列),生产者之后再发送消息时能直接从NameServer中获取到路由信息,便不会再向TBW102获取信息,相当于OrderTopic只有这4个队列了,并且只遍布在broker-a上,这意味着:自动创建无法让Topic均匀分布到集群的所有Broker上。
生产环境的建议
- 关闭自动创建:设置
autoCreateTopicEnable=false,这是5.x版本的默认行为,也是官方强烈推荐的做法。 - 手动创建Topic:通过管理命令或控制台,指定Topic名、集群名以及期望的队列数,这样可以在所有Broker上均匀创建队列,充分利用集群资源
浙公网安备 33010602011771号