Kafka-消费者-KafkaConsumer分析-PartitionAssignor

Leader消费者在收到JoinGroupResponse后,会按照其中指定的分区分配策略进行分区分配,每个分区分配策略就是一个PartitionAssignor接口的实现。图是PartitionAssignor的继承结构及其中的组件。

PartitionAssignor接口中定义了Assignment和Subscription两个内部类。

进行分区分配需要的两方面的数据:Metadata中记录的集群元数据和每个Member的订阅信息。

为了用户增强对分配结果的控制,就将用户订阅信息和一些影响分配的用户自定义信息封装成Subscription,例如,"用户自定义数据"可以是每个消费者的权重。

其中,topics集合表示某Member订阅的Topic集合,userData表示用户自定义的数据。

PartitionAssignor接口提供了subscription方法,用于添加用户自定义数据,在创建JoinGroupRequest的时候会用到subscription()方法。

Assignment中保存了分区的分配结果,partitions表示的是分配给某消费者的TopicPartition集合,userData是用户自定义的数据。

再来看看PartitionAssignor的其他方法,assign是子类要实现的、完成Parition分配的抽象方法。

onAssignment()方法是在每个消费者收到Leader分配结果时的回调函数,此调用发生在解析SyncGroupResponse之后。

AbstractPartitionAssignor为了简化PartitionAssignor接口的实现,对assign()方法进行了实现,其中会将Subscription中的userData去除掉后,再进行分区分配。具体代码如下:

RangeAssignor和RoundRobinAssignor都是Kafka提供的PartitionAssignor接口的默认实现。

  • RangeAssignor实现原理是:针对每个Topic,n=分区数/消费者数量,m=分区数%消费者数量,前m个消费者每个分配n+1个分区,后面的(消费者数量-m)个消费者每个分配n个Partition。
  • RoundRobinAssignor原理是:将所有Topic的Partition按照字典序排列,然后对每个Consumer进行轮询分配。
    举个例子,有C0、C1两个消费者和t0、t1两个Topic,每个Topic有三个分区编号都是0~2。使用RangeAssignor的分配结果是:C0:[t0p0,t0p1,t1p0,t1p1],C1:[t0p2,t1p2];使用RoundRobinAssignor的分配结果是:C0:[t0p0,t0p2,t1p1]、C1:[t0p1,t1p0,t1p2]。
相关推荐
xuyanqiangCode25 分钟前
八、Linux二进制安装Kafka集群
linux·运维·kafka
夜行容忍4 小时前
Kafka 和 RabbitMQ对比
分布式·kafka·rabbitmq
一切如来心秘密4 小时前
kafka 实现精确一次性语义实践总结
大数据·kafka
MarkHD4 小时前
kafka--发布-订阅消息系统
分布式·kafka
just-julie5 小时前
Redis 分布式集群方案 Cluster
数据库·redis·分布式
☀️5 小时前
Kafka如何防止消息重复发送
分布式·kafka·消息
青山不改眼前人6 小时前
Kafka抛弃Zookeeper后如何启动?
后端·zookeeper·kafka
程序届的悟空6 小时前
【kafka】可视化工具cmak(原kafka-manager)安装&问题解决
分布式·kafka
Akamai中国6 小时前
Akamai+Noname强强联合 | API安全再加强
分布式·云原生·云计算·云服务·akamai
java6666688888 小时前
在Spring Boot中集成分布式日志收集方案
spring boot·分布式·jenkins