Kafka -- 消费者组
消费者组
- 消费者组(Consumer Group)是Kafka提供的可扩展且具有容错性的消费者机制
- 一个消费者组内可以有多个消费者或消费者实例(进程/线程),它们共享一个Group ID(字符串)
- 组内的所有消费者协调在一起来消费订阅主题的所有分区
- 每个分区只能由同一个消费者组内的一个Consumer实例来消费,Consumer实例对分区有所有权
消息引擎模型
- 两种模型:点对点模型(消息队列)、发布订阅模型
- 点对点模型(传统的消息队列模型)
- 缺陷/特性:消息一旦被消费、就会从队列中被删除,而且只能被下游的一个Consumer消费
- 伸缩性很差,下游的多个Consumer需要抢占共享消息队列中的消息
- 发布订阅模型
- 缺陷:伸缩性不高,每个订阅者都必须订阅主题的所有分区(全量订阅)
- 点对点模型(传统的消息队列模型)
- Consumer Group
- 当Consumer Group订阅了多个主题之后
- 组内的每个Consumer实例不要求一定要订阅主题的所有分区,只会消费部分分区的消息
- Consumer Group之间彼此独立,互不影响,它们能够订阅相同主题而互不干涉
- Kafka使用Consumer Group机制实现了传统消息引擎系统的两种模型
- 如果所有Consumer实例都属于同一个Consumer Group,实现的是点对点模型
- 如果所有Consumer实例都属于不同的Consumer Group,实现的是发布订阅模型
Consumer实例数量
- 理想情况下,_Consumer实例的数量 == 该Consumer Group订阅主题的分区总数_
- 假设一个Consumer Group订阅了3个主题,分别为A(1分区)、B(2分区)、C(3分区),应该设置6个Consumer实例
- 如果只有3个实例,每个实例大约消费2个分区
- 如果有8个实例,有两个实例不会被分配到任何分区,永远处于空闲状态,浪费资源
位移管理
- 位移可类比为
Map<TopicPartition, Long>
,TopicPartition代表一个分区,Long代表位移的类型 - 老版本的Consumer Group把位移保存在Zookeeper中
- Apache Zookeeper是一个分布式的协调服务框架,Kafka重度依赖ZK实现各种各样的协调管理
- 好处:减少Kafka Broker端的状态保存开销,节点无状态,可以自由扩缩容,实现超强的伸缩性
- 但ZK这类框架并不适合进行频繁的写更新,而Consumer Group的位移更新却是一个非常频繁的操作
- 大吞吐量的写操作会极大地拖慢ZK集群的性能
- 因此,将Consumer位移保存在ZK中是不合适的做法
- 在新版本的Consumer Group中,重新设计了Consumer Group的位移管理方式(内部主题:**
__consumer_offsets
**)
重平衡
- Rebalance本质上是一种协议,规定了一个Consumer Group下所有的Consumer如何达成一致来分配分区
- Rebalance的触发条件
- 组内消费者数发生变更
- 订阅主题数发生变更
- Consumer Group可以使用正则表达式的方式订阅主题
- 订阅主题的分区数发生变更
- Kafka当前只允许增加一个主题的分区数
- Rebalance发生时,Group下所有的Consumer实例都会协调在一起共同参与
- Kafka尽量保证提供最公平的分配策略,即每个Consumer实例能够得到较为平均的分区数
- 缺陷
- Rebalance过程对Consumer Group消费过程有极大的影响
- 在Rebalance过程中,所有Consumer实例都会停止消费,等待Rebalance完成
- 所有Consumer实例共同参与,全部重新分配所有分区
- 更高效的分配方案:尽量少改动,这样可以复用已经建立的TCP连接
- Rebalance的过程可能会持续很久
- Rebalance过程对Consumer Group消费过程有极大的影响
参考资料
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.