一.【面试】Consumer消费者机制和分区策略讲解《上》
1.1. Kafka的Consumer消费者机制和分区策略讲解
消费者根据什么模式从broker获取数据的?
为什么是pull模式,而不是broker主动push?
消费者采用 pull 拉取方式,从broker的partition获取数据
pull 模式则可以根据 consumer 的消费能力进行自己调整,不同的消费者性能不一样
如果broker没有数据,consumer可以配置 timeout 时间,阻塞等待一段时间之后再返回
如果是broker主动push,优点是可以快速处理消息,但是容易造成消费者处理不过来,消息堆积和延迟。
消费者从哪个分区进行消费?
一个 topic 有多个 partition,一个消费者组里面有多个消费者,那是怎么分配呢?
1.一个主题topic可以有多个消费者,因为里面有多个partition分区 ( leader分区)
2.一个partition leader可以由一个消费者组中的一个消费者进行消费
3.一个 topic 有多个 partition,所以有多个partition leader,给多个消费者消费,那分配策略如何?
1.2.【面试】Consumer消费者机制和分区策略讲解《下》
消费者从哪个分区进行消费?两个策略
顶层接口
org.apache.kafka.clients.consumer.internals.AbstractPartitionAssignor
round-robin (RoundRobinAssignor非默认策略)轮训
【按照消费者组】进行轮训分配,同个消费者组监听不同主题也一样,是把所有的 partition 和所有的 consumer 都列出来, 所以消费者组里面订阅的主题是一样的才行,主题不一样则会出现分配不均问题,例如7个分区,同组内2个消费者
topic-p0/topic-p1/topic-p2/topic-p3/topic-p4/topic-p5/topic-p6
c-1: topic-p0/topic-p2/topic-p4/topic-p6
c-2:topic-p1/topic-p3/topic-p5
弊端
如果同一消费者组内,所订阅的消息是不相同的,在执行分区分配的时候不是轮询分配,可能会导致分区分配的不均匀
有3个消费者C0、C1和C2,他们共订阅了 3 个主题:t0、t1 和 t2
t0有1个分区(p0),t1有2个分区(p0、p1),t2有3个分区(p0、p1、p2))
消费者C0订阅的是主题t0,消费者C1订阅的是主题t0和t1,消费者C2订阅的是主题t0、t1和t2
range (RangeAssignor默认策略)范围
【按照主题】进行分配,如果不平均分配,则第一个消费者会分配比较多分区, 一个消费者监听不同主题也不影响,例如7个分区,同组内2个消费者
topic-p0/topic-p1/topic-p2/topic-p3/topic-p4/topic-p5//topic-p6
c-1: topic-p0/topic-p1/topic-p2/topic-p3
c-2:topic-p4/topic-p5/topic-p6
弊端
只是针对 1 个 topic 而言,c-1多消费一个分区影响不大
如果有 N 多个 topic,那么针对每个 topic,消费者 C-1 都将多消费 1 个分区,topic越多则消费的分区也越多,则性能有所下降
1.3 【面试】Consumer重新分配策略和offset维护机制
什么是Rebalance操作?
kafka 怎么均匀地分配某个 topic 下的所有 partition 到各个消费者,从而使得消息的消费速度达到最快,
这就是平衡(balance),前面讲了 Range 范围分区 和 RoundRobin 轮询分区,也支持自定义分区策略。
而 rebalance(重平衡)其实就是重新进行 partition 的分配,从而使得 partition 的分配重新达到平衡状态
例如70个分区,10个消费者,但是先启动一个消费者,后续再启动一个消费者,这个会怎么分配?
Kafka 会进行一次分区分配操作,即 Kafka 消费者端的 Rebalance 操作 ,下面都会发生rebalance操作
当消费者组内的消费者数量发生变化(增加或者减少),就会产生重新分配patition分区数量发生变化时
(即 topic 的分区数量发生变化时)
当消费者在消费过程突然宕机了,重新恢复后是从哪里消费,会有什么问题?
消费者会记录offset,故障恢复后从这里继续消费,这个offset记录在哪里?
记录在zk里面和本地,新版默认将offset保证在kafka的内置topic中,名称是 __consumer_offsets
该Topic默认有50个Partition,每个Partition有3个副本,分区数量由参数offset.topic.num.partition配置
通过groupId的哈希值和该参数取模的方式来确定某个消费者组已消费的offset保存到__consumer_offsets
主题的哪个分区中由 消费者组名+主题+分区,确定唯一的offset的key,从而获取对应的值三元组:
group.id+topic+分区号,而 value 就是 offset 的值
二.Kafka的Rebalance机制可能造成的影响及解决方案
2.1 kafka的rebalance机制
在kafka中,当所有新消费者加入或者订阅的topic数发生变化的时候,会触发Rebalance。(再均衡:在同一个消费者组当中,分区的所有权从一个消费者转移到另外一个消费者)机制,Rebalance顾名思义就是重新均衡消费者消费。
Rebalance的过程如下:
第一步:所有消费成员都向Coordinator发送请求,请求入Consumer Group。一旦所有成员都发送了请求,Coor
dinator会从中选择一个Consumer担任Leader的角色,并把组成员信息以及订阅信息发给Leader。
第二步:Leader开始分配消费方案,指明具体哪个Consumer负责消费哪些Topic的哪些Partition。一旦完成分配,
leader会将这个方案发给Coordinator。Coordinator接收到分配方案之后会把方案发给各个Consumer,这样
组内的所有成员就都知道自己应该消费哪些分区了。
所以对于Rebalance来说,Coordinator起着至关重要的作用
2.2 rebalance可能发生的时机
1.分区个数的增加
2.对topic的订阅发生变化
3.消费组成员的加入或离开(这个是我们最常遇到)
2.3 rebalance的影响
Rebalance对我们数据的影响主要有以下几点:
1.可能重复消费:Consumer被踢出消费组,可能还没有提交offset,Rebalance时会Partition重新分配其它Con
sumer,会造成重复消费,虽有幂等操作但耗费消费资源,亦增加集群压力
2.集群不稳定:Rebalance扩散到整个ConsumerGroup的所有消费者,因为一个消费者的退出,导致整个Group进
行了Rebalance,并在一个比较慢的时间内达到稳定状态,影响面较大.
3.影响消费速度:频繁的Rebalance反而降低了消息的消费速度,大部分时间都在重复消费和Rebalance
三.避免rebalance措施
3.1 业务需要不可避免
(1)针对分区个数的增加, 一般不会常有,是需要增加的时候都是业务及数据需求,不可避免
(2)对Topic的订阅增加或取消亦不可避免
3.2 合理设置消费者参数
下边是我们遇到的,要格外关注及重视
(1)未能及时发送心跳而Rebalance
session.timeout.ms 一次session的连接超时时间
heartbeat.interval.ms 心跳时间,一般为超时时间的1/3,Consumer在被判定为死亡之前,能够发送至少 3 轮的心跳请求
(2)Consumer消费超时而Rebalance
max.poll.interval.ms 每隔多长时间去拉取消息。合理设置预期值,尽量但间隔时间消费者处理完业务逻辑,否则就会被coordinator判定为死亡,踢出Consumer Group,进行Rebalance
max.poll.records 一次从拉取出来的数据条数。根据消费业务处理耗费时长合理设置,如果每次max.poll.interval.ms 设置的时间较短,可以max.poll.records设置小点儿,少拉取些,这样不会超时。
总之,尽可能在max.poll.interval.ms时间间隔内处理完max.poll.records条消息,让Coordinator认为消费
Consumer还活着