微信公众号「后端进阶」,专一后端技术分享:Java、Golang、WEB框架、分布式中间件、服务治理等等。
当集群中有新成员加入,或者某些主题增长了分区以后,消费者是怎么进行从新分配消费的?这里就涉及到重平衡(Rebalance)的概念,下面我就给你们讲解一下什么是 Kafka 重平衡机制,我尽可能作到图文并茂通俗易懂。后端
重平衡跟消费组紧密相关,它保证了消费组成员分配分区能够作到公平分配,也是消费组模型的实现,消费组模型以下:微信
从图中能够找到消费组模型的几个概念:session
要想实现以上消费组模型,那么就要实现当外部环境变化时,好比主题新增了分区,消费组有新成员加入等状况,实现动态调整以维持以上模型,那么这个工做就会交给 Kafka 重平衡机制去处理。框架
Kafka 重平衡机制的一些实现相比 RocketMQ 仍是有些区别的,但最终的目的仍是都是同样,就是保证分区(RocketMQ 是队列)公平分配且只能被一个消费者订阅(同一个消费组)。分布式
Kafka 重平衡:spa
从图中可看出,Kafka 重平衡是外部触发致使的,触发 Kafka 重平衡的有如下几种状况:线程
每一个消费者都会跟 Coordinator 保持心跳,当以上状况发生时,心跳响应就会包含 REBALANCE_IN_PROGRESS 命令,消费者中止消费,加入到重平衡事件当中。3d
RocketMQ重平衡:中间件
RocketMQ 消费者启动时,会开启两条线程,一条线程执行拉取消息任务,另外一条线程者则定时执行重平衡任务,从图中可看出拉取消息线程会从 pullRequestQueue 中取出拉取任务,pullRequestQueue 是一个阻塞队列,意味着当 pullRequestQueue 队列中元素为空时,会一直阻塞,直到有新的拉取任务,那么若是添加新的任务到阻塞队列中去呢?这时 RocketMQ 的重平衡做用就来了,它会每隔 20s 从任意一个 Broker 节点获取消费组的消费 ID 以及订阅信息,再根据这些订阅信息进行分配,而后将分配到的信息封装成 pullRequest 对象 pull 到 pullRequestQueue 队列中,拉取线程唤醒后执行拉取任务。对象
在消费者启动时,某些参数会影响重平衡机制的发生,因此须要根据业务的属性,对这些参数进行调优,不然可能会由于设置不当致使频繁重平衡,严重影响消费速度,下面跟你们说说这几个参数的一些要点:
该参数是 Coordinator 检测消费者失败的时间,即在这段时间内客户端是否跟 Coordinator 保持心跳,若是该参数设置数值小,能够更早发现消费者崩溃的信息,从而更快地开启重平衡,避免消费滞后,可是这也会致使频繁重平衡,这要根据实际业务来衡量。
消费者处理消息逻辑的最大时间,对于某些业务来讲,处理消息可能须要很长时间,好比须要 1分钟,那么该参数就须要设置成大于 1分钟的值,不然就会被 Coordinator 剔除消息组而后重平衡。
该参数跟 session.timeout.ms 紧密关联,前面也说过,只要在 session.timeout.ms 时间内与 Coordinator 保持心跳,就不会被 Coordinator 剔除,那么心跳间隔的时间就是 session.timeout.ms,所以,该参数值必须小于 session.timeout.ms,以保持 session.timeout.ms 时间内有心跳。
下面我用图来形象表达这三个参数的含义:
在新版本中,消费组的协调管理已经依赖于 Broker 端某个节点,该节点便是该消费组的 Coordinator, 而且每一个消费组有且只有一个 Coordinator,它负责消费组内全部的事务协调,其中包括分区分配,重平衡触发,消费者离开与剔除等等,整个消费组都会被 Coordinator 管控着,在每一个过程当中,消费组都有一个状态,Kafka 为消费组定义了 5 个状态,以下:
能够看出,重平衡发生在 PreparingRebalance 和 AwaitingSync 状态机中,重平衡主要包括如下两个步骤:
根据重平衡触发的条件,重平衡的工做流程大概有如下几种类型:
有新的成员加入消费组:
消费组成员崩溃
消费组成员主动离开
消费组成员提交位移时
关注公众号回复关键字「后端」免费领取后端开发大礼包!