Kafka系列(15)消费者组到底是什么?
Kafka消费者组
Consumer Group 是Kafka提供得可扩展得具有容错性得消费者机制。
既然是组,那么组内必然是可以有多个消费者或消费者实例(Consumer Instance)
它们共享一个共同得Id,这个Id被称为Group ID.组内的所有消费者协调在一起消费订阅主题(Subscribed Topics)的所有分区(Partition)。当然每个分区只能有同一个消费者组内的一个Consumer实例来消费。
三个特性:
1.Consumer Group 下可以有一个或多个Consumer实例。这里的实例可以是一个单独的进程,也可以是同一个进程下的线程。
2 Group ID 是一个字符串,在一个Kafka集群中,它标识唯一的一个Consumer Group
3 Consumer Group下所有的实例订阅的主题的单个分区,只能分配组内的某个Consumer实例消费。这个分区当然可以被其他的Group消费。
传统的消息队列模型的缺陷在于消息一旦被消费,就会从队列中被删除,而且只能被下游的一个Consumer消费。严格来说,这一点不算是缺陷,只能算是它的一个特性。但很显然,这种模型的伸缩性很差,因为下游的多个Consumer都要抢这个共享的消息队列的消息。发布/订阅模型倒是允许消息被多个Consumer消费,但它的问题也是伸缩性不高,因为每个订阅者都必须要订阅主题的所有分区。这种全量订阅的方式既不灵活,也会影响消息的真实投递效果。
当Consumer Group订阅多个主题后,组内的每个实例不要求一定要订阅主题的所有分区,它只会消费部分分区中的消息。
Consumer Group 之间彼此独立,互补影响,它们能够订阅相同的一组主题而互不干涉。再加上Broker端的消息留存机制,Kafka
的Consumer完美规避了上面提到的伸缩性差的问题。
Kafka仅仅使用Consumer Group这一种机制,却同时实现了传统消息引擎的两大模型:如果所有实例都属于同一个Group,那么她实现的就是消息队列模型;有实例分别属于不同的Group,那么他实现的就是发布/订阅模型。
理想情况下,Conusmer实例的数量应该等于Group订阅主题的分区总数。
举个简单的例子,假设一个Consumer Group 订阅了三个主题,分别是A\B\C,它们的分区数依次是1、2、3,那么通常情况下
为该Group设置6个Consumer实例是比较理想的情形,因为它最大限度地实现高伸缩性。
在实际使用过程中一般不推荐设置大于总分区数地Consumer实例,设置多余地实例只会浪费资源。
对于Consumer Group而言,它是一组KV对,Key是分区,V对应Consumer消费该分区的最新位移。
如果用Java来表示的话,Map<TopicPatition,Long> 其中TopicPartition表示一个分区,而Long表示位移的类型。
老版本的Consumer Group把位移保存在Zookeeper中,zookeeper是一个分布式的协调服务框架,kafka重度依赖它实现各种各样的协调管理。将位移保存在Zookeeper外部系统得做法,最显而易见得好处就是减少了Kafka Broker端状态保存开销。
现在比较流行得提法是将服务器节点做成无状态的,这样可以自由地扩展扩容,实现超强地伸缩性。
Kafka社区重新设计了Consumer Group 位移管理方式,采用了将位移保存在Kafka内部主题地方法。这个主题就是让人既爱又恨地_consumer_offsets 需要记住新版本地Consumer Group将位移保存在Broker端地内部主题中。
Rebalance本质上是一种协议,规定了一个Consumer Group下的所有Consumer如何达成一致,来分配订阅Topic
的每个分区。比如某个Group下有20个Consumer实例,它订阅了一个具有100个分区的Topic.正常情况下,Kafka平均会为
每个Consumer分配5个分区。这个分配的过程就叫做Rebalance.
Rabalance的触发条件有三个:
1组成员数发生变更,比如有新的Consumer实例加入组或者离开组,抑或是有Consumer实例崩溃被踢出组。
2订阅主题数发生变更。Consumer Group可以使用正则表达式的方式订阅主题,比如consumer.subscribe就表明Group
订阅所有以字母t开头、字母c结尾的主题。在Consumer Group的运行过程中,你创建了一个满足这样条件的主题,该Group
就会发生Rebalance.
3订阅主题的分区数发生变更,Kafka当前只能允许增加一个主题的分区数,当分区数增加时,就会触发订阅该主题的所有Group
开启Rebalance
Rebalance发生时,Group下所有的Consumer实例都会协调在一起共同的参与。
三种分配策略,保证提供最公平的分配策略,即每个Conusmer实例都能够得到较为平均的分区数;比如一个Group
内有10个Consumer实例,要消费100个分区,理想的分配策略自然是每个实例得到10个分区。
Rebalance的弊端:
首先,Rebalance过程对Consumer Group消费过程有极大影响。Rebalance过程也和这个类似,在Rebalance过程中,所有Consumer实例都会停止消费,等待Rebalance完成。
其次,目前Rebalance的设计是所有的Consumer实例共同参与,全部重新分配所有分区,其实更高效的做法是尽量减少分配方案的变动。例如,实例A之前负责消费分区1,2,3,那么Rebalance之后,如果可能,最好还是让实例A继续消费分区1,23
而不是被重新分配其他的分区,这样的话,实例A连接这些分区所在的Broker的Tcp连接就可以继续用,不用重新创建连接其他Broker的socket资源。
- Kafka系列(17)消费者组重平衡能避免吗
- Kafka系列4-基本概念及消费者组(Consumer Group)的理解
- Kafka系列(25)消费者组重平衡全流程解析
- Kafka系列(22)消费者组消费进度监控都怎么实现?
- 从无到有系列之kafka生产消费者demo02
- Kafka系列(21)java消费者是如何管理Tcp连接的
- Kafka系列3-python版本producer生产者和consumer消费者实例
- Kafka系列之-Kafka入门
- apache kafka系列之源码分析走读-kafka内部模块分析
- 基于Kafka的生产者消费者消息处理本地调试
- 数据结构和算法系列15 线索二叉树
- Kafka 生产者和消费者 demo (java&scala)
- Kafka总结系列(一)
- mysql 开发基础系列15 索引的设计和使用
- spring-kafka消费者配置
- ExtJs2.0学习系列(15)--extjs换肤
- 中间件系列十 RabbitMQ之消费者端的消息确认机制
- 从零开始学_JavaScript_系列(15)——js系列<3>(转为字符串,截取字符串)
- kafka消费者脚本无法启动问题
- Kafka源码系列之Broker的IO服务及业务处理