理论教育 Scala语言基础与开发实战-消费者再平衡

Scala语言基础与开发实战-消费者再平衡

时间:2023-11-24 理论教育 版权反馈
【摘要】:Consumer Rebalance也叫消费者平衡机制,主要是指Cusumer消费者数量改变时,就会启动该平衡机制。Kafka保证同一Consumer Group中只有一个Consumer会被消费某条消息。理解了Consumer消费Partition关系之后,现在就比较容易了解Consumer Rebalance的算法了。目前,最新版Kafka的Consumer Rebalance的控制策略是由每一个Consumer通过在Zookeeper上注册Watch完成的。5)强制自己在其Consumer Group内启动Rebalance流程。在这种策略下,每一个Consumer或者Broker的增加或者减少都会触发Consumer Rebalance。3)调整结果不可控:所有的Consumer都并不知道其他Consumer的Rebalance是否成功,这可能会导致Kaf

Scala语言基础与开发实战-消费者再平衡

Consumer Rebalance也叫消费者平衡机制,主要是指Cusumer消费者数量改变时,就会启动该平衡机制。Kafka保证同一Consumer Group中只有一个Consumer会被消费某条消息。实际上,Kafka保证的是稳定状态下每一个Consumer实例只会消费某个或多个特定Partition的数据,而某个Partition的数据只会被某个特定的Consumer实例所消费。也就是说,Kafka对消息是以Partition为单位分配的,而非以每一条消息作为分配单元。这样设计的劣势是无法保证同一个Consumer Group里的Consumer均匀消费数据,优势是每个Consumer不需要和大量的Broker通信,减少通信开销,同时也降低了分配难度,实现也更简单。另外,因为同一个Partition里的数据是有序的,这种设计可以保证每个Partition里的数据可以被有序消费。如果某Consumer Group中Consumer数量少于Partition数量,则至少有一个Consumer会去消费多个Partition的数据;如果Consumer的数量与Partition数量相同,则正好一个Con⁃sumer消费一个Partition的数据;而如果Consumer的数量多于Partition的数量,会有部分Consumer无法消费该Topic下任何一条消息。

为了更清楚地理解上面几种情况,这里用一个简单的实例来说明,在Broker中有个一TopicA,其中有3个Partition(假设分别为0、1、2)。在Customer中,当只有一个属于group1的Consumer实例(假设名称为ConsumerA)时,此时ConsumerA可消费TopicA上3个Partition的数据;现在再增加一个Consumer实例(假设名称为ConsumerB),这样,如果其中的一个Customer(假设是ConsumerA)可以消费两个Partition(假设是Partition 0和Par⁃tition 1)数据,另一个Customer(假设是ConsumerB)可以消费余下的Partition(Partition 2)数据;现在继续增加一个Consumer实例(假设名称为ConsumerC)。这时,每个Consumer可消费一个Partition的数据,ConsumerA消费partition0,ConsumerB消费partition1,Consum⁃erC消费partition2。现在继续再增加一个Consumer实例(假设名称为ConsumerD),这时,其中3个Consumer可分别消费一个Partition的数据,另外一个Consumer(假设是Consum⁃erD)不能消费topicA的任何数据。再做个逆操作,看看Customer消费情况,先关闭Con⁃sumerA,其余3个Consumer可分别消费其中一个Partition的数据;接着关闭ConsumerB,ConsumerC可消费两个Partition,ConsumerD可消费一个Partition;再关闭ConsumerC,仅存的ConsumerD可同时消费topicA的3个Partition。

理解了Consumer消费Partition关系之后,现在就比较容易了解Consumer Rebalance的算法了。下面大家来看看Consumer Rebalance算法流程:

1)将目标Topic下的所有Partirtion排序,存于PT。

2)对某Consumer Group下的所有Consumer排序,存于CG,第i个Consumer记为Ci。

3)向上取整,计算N值,N=size(PT)/size(CG)。

4)解除Ci对原来分配的Partition的消费权(i从0开始)。

5)将第i∗N到(i+1)∗N-1个Partition分配给Ci。

目前,最新版(0.8.2.1)Kafka的Consumer Rebalance的控制策略是由每一个Consumer通过在Zookeeper上注册Watch完成的。每个Consumer被创建时会触发Consumer Group的Rebalance,具体启动流程如下:

1)High Level Consumer启动时将其ID注册到其Consumer Group下,在Zookeeper上的路径为/consumers/[consumer group]/ids/[consumer id]。

2)在/consumers/[consumer group]/ids上注册Watch。(www.daowen.com)

3)在/brokers/ids上注册Watch。

4)如果Consumer通过Topic Filter创建消息流,则它会同时在/brokers/topics上也创建Watch。

5)强制自己在其Consumer Group内启动Rebalance流程。

在这种策略下,每一个Consumer或者Broker的增加或者减少都会触发Consumer Rebal⁃ance。因为每个Consumer只负责调整自己所消费的Partition,为了保证整个Consumer Group的一致性,当一个Consumer触发了Rebalance时,该Consumer Group内的其他所有Consumer也应该同时触发Rebalance。

上面这种策略,存在如下缺陷:

1)Herd Effect:任何Broker或者Consumer的增减都会触发所有的Consumer的Rebal⁃ance。

2)Split Brain:每个Consumer分别单独通过Zookeeper判断哪些Broker和Consumer宕机了,那么不同Consumer在同一时刻从Zookeeper“看”到的View就可能不一样,这是由Zo⁃okeeper的特性决定的,这就会造成不正确的Reblance尝试。

3)调整结果不可控:所有的Consumer都并不知道其他Consumer的Rebalance是否成功,这可能会导致Kafka工作在一个不正确的状态。

Kafka作者正在考虑在未来的0.9.∗版本中将使用中心协调器(Coordinator)———Con⁃sumer Rewrite Design,具体思想如下:从所有Consumer Group的子集选举出一个Broker作为Coordinator,由它Watch Zookeeper,从而判断是否有Partition或者Consumer的增减,然后生成Rebalance命令,并检查是否这些Rebalance在所有相关的Consumer中被执行成功,如果不成功则重试,若成功则认为此次Rebalance成功(这个过程跟Replication Controller非常类似)。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈