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]。
相关推荐
DemonAvenger12 小时前
Kafka性能调优:从参数配置到硬件选择的全方位指南
性能优化·kafka·消息队列
初次攀爬者14 小时前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
yumgpkpm2 天前
AI视频生成:Wan 2.2(阿里通义万相)在华为昇腾下的部署?
人工智能·hadoop·elasticsearch·zookeeper·flink·kafka·cloudera
予枫的编程笔记2 天前
【Kafka高级篇】避开Kafka原生重试坑,Java业务端自建DLQ体系,让消息不丢失、不积压
java·kafka·死信队列·消息中间件·消息重试·dlq·java业务开发
倚肆2 天前
在 Windows Docker 中安装 Kafka 并映射 Windows 端口
docker·kafka
断手当码农2 天前
Redis 实现分布式锁的三种方式
数据库·redis·分布式
Sheffield2 天前
如果把ZooKeeper按字面意思比作动物园管理员……
elasticsearch·zookeeper·kafka
初次攀爬者2 天前
Redis分布式锁实现的三种方式-基于setnx,lua脚本和Redisson
redis·分布式·后端
雪碧聊技术2 天前
kafka的下载、安装、启动
kafka