消费者消费的时候,需要指定去消费哪个Topic的消息,比如TopicTest。

和生产者一样,消费者也需要去NameServer拉取TopicTest对应的元数据信息。

image.png

如上图所示,TopicTest对应这两个broker,每个broker都有两个MessageQueue,那消费者从哪里拉取数据呢?

比如我们有两个消费者,消费者在启动的时候,会向每个broker发送心跳包,这样每一个broker都有消费者的信息,我们也可以从任意一个broker获取所有消费者的信息。

既然有了元数据信息,还有消费者的信息,那就可以通过分配算法,知道当前这个消费者去哪个MessageQueue拉取数据。

目前RocketMQ默认提供6种分配算法,包括平均分配(AllocateMessageQueueAveragely)、平均轮询分配(AllocateMessageQueueAveragelyByCircle)、一致性hash(AllocateMessageQueueConsistentHash)、根据配置(AllocateMessageQueueByConfig)、根据Broker部署机房名(AllocateMessageQueueByMachineRoom)、就近机房模式(AllocateMachineRoomNearby)。

默认是平均分配,比如有4个MessageQueue,那两个消费者各2个。消费者1分配的是MessageQueue0和MessageQueue1,消费者2分配MessageQueue2和MessageQueue3。

如果是平均轮询分配,那消费者1分配1个,消费者2分配1个,消费者1再分配一个,消费者2再分配一个,最终消费者1分配的是MessageQueue0和MessageQueue2,消费者2分配MessageQueue1和MessageQueue3。

我们接着平均分配进行往下说,以消费者1为例。

image.png

此时已经知道消费者从MessageQueue0和MessageQueue1来消费,那从哪里开始消费呢?

消费的模式又分为从队列最新偏移量开始消费(CONSUME_FROM_LAST_OFFSET)、从头开始消费(CONSUME_FROM_FIRST_OFFSET)、从消费者启动的时间戳对应的消费进度开始消费(CONSUME_FROM_TIMESTAMP)。

根据以上的信息,我们就可以整合一个请求信息PullRequest,包括消费组、偏移量、MessageQueue、ProcessQueue(这个后面来解释),存放在pullRequestQueue链表里。

image.png


大军
847 声望183 粉丝

学而不思则罔,思而不学则殆