当前位置: 首页 > 科技观察

阿里二面:RocketMQ消费者在同一个消费组订阅不同的标签,会不会有什么问题?

时间:2023-03-21 23:34:47 科技观察

面试官:如果同一个消费群的消费者订阅了同一个topic,但是订阅了不同的tag,会不会有什么问题?我:消息会丢失。面试官:能详细解释一下吗?我:RocketMQ要求同一个消费组中的消费者有相同的订阅关系。如果订阅关系不一致,消息就会丢失。面试官:什么是一致的订阅关系?我:一致的订阅关系是指同一个消费组下的所有消费者订阅的主题和标签必须完全一致。如下图所示:其中,消费组1中的消费组订阅了Topic1中的Tag1,消费组2中的消费组订阅了Topic1中的所有Tag和Tag1||Topic2中的Tag2,消费组3中的消费组都订阅了Topic2中的所有消费组Tag1和Tag2。采访者:您能举一些不一致订阅关系的例子吗?我:订阅不一致的情况有3种,如下图:消费组1??的Consumer1和Consumer2都订阅了Topic1,但是订阅的Tag不一致。消费组2的Consumer1和Consumer2订阅的topic不一致。消费组3的Consumer1和Consumer2订阅的Topics和Tags一致,但是Tags的订阅顺序不一致。面试官:为什么不一致的订阅关系会导致消息丢失?我:RocketMQ的存储架构,如下图所示:RocketMQ为了提高消费效率,引入了ConsumeQueue,将消息的物理偏移量存储在CommitLog文件中。ConsumerQueue中的元素内容如下:前8个字节记录了消息在CommitLog中的偏移量。中间4个字节记录消息大小。最后8个字节记录消息中标签的哈希码。这个标签的作用是过滤消息。如果一个Consumer订阅了Topic1中的Tag1,那么Consumer在拉取消息时,首先从NameServer获取订阅关系,获取当前Consumer订阅的所有标签的hashcode集codeSet。每次从ConsumerQueue中获取一条记录,都需要判断taghashcode的后8字节是否在codeSet中。例如,如果Tag2不在codeSet中,它将被过滤掉。如下图所示:消费者组1消费Topic1中的消息时,Consumer1通过ConsumeQueue1和ConsumeQueue2消费,Consume2通过ConsumeQueue3和ConsumeQueue4消费。如果Consumer1订阅了Tag1,Consumer2订阅了Tag2,那么当Consumer1消费ConsumeQueue1和ConsumeQueue2中的消息时,Tag2中的消息会被过滤掉,这样即使Consumer2订阅了Tag2,也无法在ConsumeQueue1和ConsumeQueue2中消费Tag2中的消息.面试官:有没有办法快速知道消费组中是否存在不一致的订阅关系?我:在RocketMQ控制台上可以看到。在RocketMQ实例列表中,进入Group管理页面,查看要查找的GroupID,查看详情,如下图:(下图来自阿里云)面试官:恭喜你通过了。

猜你喜欢