您的位置:首页 > 其它

Kafka系列(15)消费者组到底是什么?

2019-07-07 16:27 330 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_18522601/article/details/94990036

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资源。

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: