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]。
相关推荐
一个有温度的技术博主2 小时前
告别“竹篮打水”:Redis单点瓶颈与分布式缓存架构全解析
redis·分布式·缓存
殷紫川2 小时前
吃透 MinIO:从底层架构到全场景文件上传下载实战,一篇搞定企业级对象存储
分布式·后端
却话巴山夜雨时i3 小时前
Java面试实录:从Spring Boot到Kafka的技术探讨
spring boot·微服务·kafka·grafana·prometheus·java面试
橘子编程3 小时前
Spark全栈指南:从入门到精通
大数据·分布式·spark
Abcdzzr4 小时前
2026/4/6 Windows安装Kafka
分布式·kafka
zxfBdd4 小时前
Spark Map算子异常处理方法
大数据·分布式·spark
一个有温度的技术博主4 小时前
告别单点瓶颈:Redis主从架构与读写分离实战
redis·分布式·缓存·架构
哦豁灬5 小时前
bitbrick_k1集群使用prima_cpp分布式部署大模型推理
分布式
枫叶林FYL5 小时前
【Python高级工程与架构实战】项目二:事件驱动微服务拆分(分布式版)
分布式·微服务·架构
大力财经5 小时前
云访谈 203:她在资阳,下注 “换电电动车 + 分布式换电站” 新未来
分布式