Consumer Group
提及Consumer Group,最先想到的就是Group与Consumer Client的关联关系:
- 1,Consumer Group用group.id(String)作为全局唯一标识符
- 2,每个Group可以有零个、一个或多个Consumer Client
- 3,每个Group可以管理零个、一个或多个Topic
- 4,Group下每个Consumer Client可同时订阅Topic的一个或多个Partition
- 5,Group下同一个Partition只能被一个Client订阅,多Group下的Client订阅不受影响
Consumer Group的作用主要有:管理Partition的Offset信息;管理Consumer Client与Partition的分配。正因为所有Partition的Offset信息是由Group统一管理,所以如果一个Partition有多个Consumer,那么每个Consumer在该Partition上的Offset很可能会不一致,这样会导致在Rebalance后赋值处理的Client的消费起点发生混乱;与此同时,这种场景也不符合Kafka中Partition消息消费的一致性;因此在同一Group下一个Partition只能对应一个Consumer Client。
接下来将通过介绍Group的管理者Coordinator来了解Group是如何管理Offset;此外通过介绍Group的Rebalance机制了解Partition分配的原理,并介绍如何通过代码实现Rebalance的监控。下图是笔者基于自己的理解总结绘制的逻辑图,有不对的地方还请指正:
Group Coordinator
Group Coordinator是一个服务,每个Broker在启动的时候都会启动一个该服务。Group Coordinator的作用是用来存储Group的相关Meta信息,并将对应Partition的Offset信息记录到Kafka内置Topic(__consumer_offsets)中。Kafka在0.9之前是基于Zookeeper来存储Partition的Offset信息(consumers/{group}/offsets/{topic}/{partition}),因为ZK并不适用于频繁的写操作,所以在0.9之后通过内置Topic的方式来记录对应Partition的Offset。
每个Group都会选择一个Coordinator来完成自己组内各Partition的Offset信息,选择的规则如下:
- 1,计算Group对应在__consumer_offsets上的Partition
- 2,根据对应的Partition寻找该Partition的leader所对应的Broker,该Broker上的Group Coordinator即就是该Group的Coordinator
Partition计算规则
partition-Id(__consumer_offsets) = Math.abs(groupId.hashCode() % groupMetadataTopicPartitionCount)
其中groupMetadataTopicPartitionCount对应offsets.topic.num.partitions参数值,默认值是50个分区
查看指定Partition各Replica的分布情况
bin/kafka-topics.sh --zookeeper <address:port> --topic __consumer_offsets --describe
Group Coordinator Generation
Group Coordinaror是Group Rebalance中不可或缺的一环,因为Coordinator负责记录了每次Rebalance后的Partition分配结果,因此Kafka为Coordinator赋予了一个Gene