什么时机触发Rebalance
Kafka 消费组发生重平衡的条件有以下几个:
消费组成员发生变更,有新消费者加入或者离开,或者有消费者崩溃;
消费组订阅的主题数量发生变更;
消费组订阅的分区数发生变更。
总的来说就是: 消费中的消费者,主题,分区的数量其中的一点发生变化都会造成Rebalance
0.10kafka的rebalance条件
条件1:有新的consumer加入
条件2:旧的consumer挂了
条件3:coordinator挂了,集群选举出新的coordinator(0.10 特有的)
条件4:topic的partition新加
条件5:consumer调用unsubscrible(),取消topic的订阅
如何避免不必要的Rebalance
kafka的Rebalance问题分析除开consumer正常的添加和停掉导致rebalance外,在某些情况下,Consumer 实例会被 Coordinator 错误地认为 “已停止” 从而被“踢出”Group,导致rebalance,这种情况应该避免。
第一类非必要 Rebalance 是因为未能及时发送心跳,导致 Consumer 被 “踢出”Group 而引发的。这种情况下我们可以设置 session.timeout.ms 和 heartbeat.interval.ms 的值,来尽量避免rebalance的出现。(以下的配置是在网上找到的最佳实践,暂时还没测试过)
设置 session.timeout.ms = 6s。
设置 heartbeat.interval.ms = 2s。
要保证 Consumer 实例在被判定为 “dead” 之前,能够发送至少 3 轮的心跳请求,即 session.timeout.ms >= 3 * heartbeat.interval.ms。
将 session.timeout.ms 设置成 6s 主要是为了让 Coordinator 能够更快地定位已经挂掉的 Consumer,早日把它们踢出 Group。
第二类非必要 Rebalance 是 Consumer 消费时间过长导致的。此时,max.poll.interval.ms 参数值的设置显得尤为关键。如果要避免非预期的 Rebalance,你最好将该参数值设置得大一点,比你的下游最大处理时间稍长一点。
快速处理方法:
最主要的方法:
一个是增加session.timeout.ms的时间,
一个是设置不要自动提交(enable.auto.commit=false).
增加 max.poll.interval.ms处理时长,默认300s
减少 max.poll.records (每次拉取消息的条数)默认500
设置 session.timeout.ms = 30s。
设置 heartbeat.interval.ms = 10s。
session.timeout.ms 这个是消费者维护session的最大时间,如果在这个时间内消费者没有上报状态则认为消费者已经断开,max.poll.interval.ms这个是拉取的最大时间间隔,如果你一次拉取的比较多,建议加大这个值,heartbeat.interval.ms这个是通知消费者重新连接的间隔时间,这个值要比session.timeout.ms小,最好不要超过最好不要超过heartbeat.interval.ms的三分之一,在我们环境中我们把超时时间修改成60s后rebalance问题得到解决,这些参数都是针对具体场景设置,不要盲从!
大概的意思是消费者的消费速度小于生产者的产生速度,所以导致了消息堆积,但是通过之前的测试可以知道.消费者的速度其实是远大于生产者的. 那么是什么原因呢? 真相只有一个:重复消费!
consumer在堆积的消息队列中拿出部分消息来消费,但是这个拿取是随机的(不确定,目前看来是),如果生产者一次产生的数据量过大,1秒钟5W条,那么consumer是有可能在规定的时间内(session.timeout.ms)消费不完的.
如果设置的是自动提交(enable.auto.commit),就会出现提交失败的情况,提交失败就会回滚,这部分数据就相当于没有被消费过,然后consumer继续去拿数据如果还没消费完就还是回滚,这样循环下去.(但是我发现有时候数据还是会被消费的,比如说数据小于两万条/次,所以我说取得数量是随机的,应该可以设置).
一个是增加session.timeout.ms的时间,
一个是设置不要自动提交(enable.auto.commit=false).
最后我采取的方案是不要自动提交,因为如果随着我增加session.timeout.ms的时间,取得数据量也增加了那还是会超时(而且我也不知道怎么设置每次取得数量)
最后成功解决问题.