1. rebalance概览

consumer group的rebalance本质上是一组协议,它规定了一个consumer group是如何达成一致来分配订阅 topic的所有分区的。假设某个组下有20个 consumer实例,该组订阅了一个有着100个分区的 topic。正常情况下,Kafka会为每个consumer平均分配5个分区。这个分配过程就被称为 rebalance。当 consumer成功地执行 rebalance后,组订阅 topic的每个分区只会分配给组内的一个consumer实例。

和旧版本consumer依托于ZooKeeper进行rebalance不同,新版本consumer使用了Kafka内置的一个全新的组协调协议(group coordination protocol)。对于每个组而言,Kafka的某个broker会被选举为组协调者(group coordinator)。coordinator负责对组的状态进行管理,它的主要职责就是当新成员到达时促成组内所有成员达成新的分区分配方案,即coordinator负责对组执行rebalance操作。

2. rebalance触发条件

1.组成员发生变更,比如新 consumer 加入组,或已有 consumer 主动离开组,再或是已有consumer崩溃时则触发rebalance
2.组订阅 topic 数发生变更,比如使用基于正则表达式的订阅,当匹配正则表达式的新topic被创建时则会触发rebalance。
3.组订阅topic的分区数发生变更,比如使用命令行脚本增加了订阅topic的分区数。

真实应用场景中引发 rebalance最常见的原因就是违背了第一个条件,特别是consumer崩溃的情况。这里的崩溃不一定就是指consumer进程“挂掉”或 consumer进程所在的机器宕机。当consumer无法在指定的时间内完成消息的处理,那么coordinator就认为该consumer已经崩溃,从而引发新一轮rebalance。

3. rebalance分区分配策略

所谓的分配策略决定了订阅topic的每个分区会被分配给哪个consumer

3种分配策略:

range 策略
round-robin策略
sticky策略
range策略主要是基于范围的思想。它将单个 topic 的所有分区按照顺序排列,然后把这些分区划分成固定大小的分区段并依次分配给每个consumer;
round-robin策略则会把所有 topic的所有分区顺序摆开,然后轮询式地分配给各个consumer。
最新发布的sticky策略有效地避免了上述两种策略完全无视历史分配方案的缺陷,采用了“有黏性”的策略对所有consumer实例进行分配,可以规避极端情况下的数据倾斜并且在两次rebalance间最大限度地维持了之前的分配方案。

通常意义上认为,如果 group 下所有 consumer 实例的订阅是相同,那么使用 round-robin会带来更公平的分配方案,否则使用range策略的效果更好。

举例说明:
假设目前某个consumer group下有两个consumer:A和B。当第3个成员C加入时,满足了前面谈到的第一个触发条件,因此coordinator会执行rebalance,并根据range分配策略重新为A、B和C分配分区
在这里插入图片描述
由此可见,原先 A和 B分别处理 3个分区的数据,rebalance之后 A、B和C各自承担2个分区的消费,可以说这个分配方案非常公平,每个consumer上的负载是相同的。

  1. bin目录下执行创建命令:
    kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic mytest
    在这里插入图片描述
  2. 查看创建的主题:命令如下:
    kafka-topics.sh --list --bootstrap-server simon:9092,simon2:9092,simon3:9092
    在这里插入图片描述
  3. 在zk中查看创建的主题:
    在这里插入图片描述
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐