一、消费组概念
Consumer Group 是 Kafka 提供的可扩展且有容错性的消费者机制。一个组里面有多个消费者实例,这些消费者共享一个ID,称为Group ID。组内的所有消费者协调在一起来消费订阅主题(Subscribed Topics)的所有分区(Partition)
二、消费组特性
- 消费组有多个消费实例。这些实例可以是单一进程也可以是同一进程下的线程
- 每个分区只能被一个消费者消费,但是一个消费者可以消费多个分区
- Group ID是一个字符串
如果所有消费实例分别属于不同的Consumer Group,就是发布订阅模式,所有消费实例只属于一个group时就是队列模式。Consumer Group 之间彼此独立,互不影响,它们能够订阅相同的一组主题而互不干涉
理想情况:
分区数 = 消费者实例
消费位移: 抽象的看成键值对,key是对应分区,value对应消费的offset
消费者过多,就会闲置,例如主题A有三个分区,如果消费组B有三个消费实例,就会每个实例消费同一个分区,如果消费实例超过3,超过部分的消费实例将会闲置。
三、消费位移管理
Kafka 有新旧Consumer API 之分,老版本的 Consumer Group 把位移保存在 ZooKeeper 中,将位移保存在 ZooKeeper 外部系统的做法,最显而易见的好处就是减少了 Kafka Broker 端的状态保存开销,将服务器节点做成无状态的好处是可以自由地扩缩容,实现超强的伸缩性
kafka巨额吞吐量,会带来频繁读写,消费位移保存在zk中,会大量消耗集群性能,所以0.9版本后将消费位移保存到broker上的一个内部主__consumer_offsets
保存在broker的优点:
- 满足频繁写入
- 可以持久化保存
新版本 Consumer 的位移管理机制其实就是将 Consumer 的位移数据作为一条条普通的 Kafka 消息,提交到 __consumer_offsets 中。位移主题就是普通的 Kafka 主题,可以手动地创建它、修改它,甚至是删除它。
位移主题有特定的消息格式,不可以随便向该主题发送消息
位移主题的key:<Group ID,主题名,分区名>
value保存的是具体的位移数值和相关元数据
其它两种格式:
- 用于保存Consumer Group信息的消息(不常见)
- 用于删除Group过期位移甚至删除group的消息,消息体是 null
Kafka集群中第一consumer启动时会创建位移主题,默认是分区50,副本数是3,也可以选择手动创建位移主题 ,但是最好不要修改这个默认值
自动提交最好关闭,否则会一直向位移主题写入最新消息,撑爆kafka
图中位移为 0、2 和 3 的消息的 Key 都是 K1。Compact 之后,分区只需要保存位移为 3 的消息,因为它是最新发送的,其余K2,K3等等都是基于上述操作
Kafka使用Compact策略删除过期消息,避免该主题无限期膨胀,会在后台起线程对比相同key的消息,删除发送时间较早的,如果kafka位移主题占用情况严重,记得检查整改Log Cleaner线程状态,查看其是否宕机
四、Consumer重平衡
Rebalance 本质上是一种协议,规定了一个 Consumer Group 下的所有 Consumer 如何达成一致,来分配订阅 Topic 的每个分区。
Group 下有 20 个 Consumer 实例,它订阅了一个具有 100 个分区的 Topic。正常情况下,Kafka 平均会为每个 Consumer 分配 5 个分区。这个分配的过程就叫 Rebalance
Rebalance 的触发条件
- 组成员数发生变更
- 订阅主题数发生变更
- 订阅主题的分区数发生变更
Rebalance 发生时,Group 下所有的 Consumer 实例都会协调在一起共同参与,Kafka 默认提供了 3 种分配策略,都是为了保证消费者可以比较平均的消费broker上的消息。
3个主题,每个主题2个分区,2个消费者,每个消费者消费3个分区数据,当第三个消费者C加入,触发重平衡,每个Consumer消费2个分区数据
Rebalance的缺点
Rebalance过程group下所有消费者停止消费,如果一个group下消费实例太多,再均衡过程会比较长
目前 Rebalance 的设计是所有 Consumer 实例共同参与,全部重新分配所有分区。其实更高效的做法是尽量减少分配方案的变动。例如实例 A 之前负责消费分区 1、2、3,那么 Rebalance 之后,如果可能的话,最好还是让实例 A 继续消费分区 1、2、3,而不是被重新分配其他的分区。这样的话,实例 A 连接这些分区所在 Broker 的 TCP 连接就可以继续用,不用重新创建连接其他 Broker 的 Socket 资源
参考:
本文是基于极客时间专栏读书笔记
极客时间—Kafka核心技术与实战