Kafka Consumer Rebalance

来源:互联网 发布:php qq授权登陆 编辑:程序博客网 时间:2024/06/05 15:31

       Kafka保证同一consumer group中只有一个consumer会消费某条消息,实际上,Kafka保证的是稳定状态下每一个consumer实例只会消费某一个或多个特定partition的数据,而某个partition的数据只会被某一个特定的consumer实例所消费。这样设计的劣势是无法让同一个consumer group里的consumer均匀消费数据,优势是每个consumer不用都跟大量的broker通信,减少通信开销,同时也降低了分配难度,实现也更简单。另外,因为同一个partition里的数据是有序的,这种设计可以保证每个partition里的数据也是有序被消费。

       如果某consumer group中consumer数量少于partition数量,则至少有一个consumer会消费多个partition的数据,如果consumer的数量与partition数量相同,则正好一个consumer消费一个partition的数据,而如果consumer的数量多于partition的数量时,会有部分consumer无法消费该topic下任何一条消息。
  如下例所示,如果topic1有0,1,2共三个partition,当group1只有一个consumer(名为consumer1)时,该 consumer可消费这3个partition的所有数据。
  

这里写图片描述

  
  增加一个consumer(consumer2)后,其中一个consumer(consumer1)可消费2个partition的数据,另外一个consumer(consumer2)可消费另外一个partition的数据。
 
 这里写图片描述

  
  再增加一个consumer(consumer3)后,每个consumer可消费一个partition的数据。consumer1消费partition0,consumer2消费partition1,consumer3消费partition2
 
 这里写图片描述 

  再增加一个consumer(consumer4)后,其中3个consumer可分别消费一个partition的数据,另外一个consumer(consumer4)不能消费topic1任何数据。
 这里写图片描述

  此时关闭consumer1,剩下的consumer可分别消费一个partition的数据。
  
这里写图片描述

  接着关闭consumer2,剩下的consumer3可消费2个partition,consumer4可消费1个partition。
  
这里写图片描述

  
  再关闭consumer3,剩下的consumer4可同时消费topic1的3个partition。
  consumer rebalance算法如下:   

  1. Sort PT (all partitions in topic T)
  2. Sort CG(all consumers in consumer group G)
  3. Let i be the index position of Ci in CG and let N=size(PT)/size
    (CG)
  4. Remove current entries owned by Ci from the partition owner registry
  5. Assign partitions from iN to (i+1)N-1 to consumer Ci
  6. Add newly assigned partitions to the partition owner registry

       目前consumer rebalance的控制策略是由每一个consumer通过Zookeeper完成的。具体的控制方式如下:
  

  1. Register itself in the consumer id registry under its group.
  2. Register a watch on changes under the consumer id registry.
  3. Register a watch on changes under the broker id registry.
  4. If the consumer creates a message stream using a topic filter, it
    also registers a watch on changes under the broker topic registry.
  5. Force itself to rebalance within in its consumer group.

      
      在这种策略下,每一个consumer或者broker的增加或者减少都会触发consumer rebalance。因为每个consumer只负责调整自己所消费的partition,为了保证整个consumer group的一致性,所以当一个consumer触发了rebalance时,该consumer group内的其它所有consumer也应该同时触发rebalance。

     0.8.2Kafka采用的是上述方式。但该方式有不利的方面:

    1, Herd effect

    任何broker或者consumer的增减都会触发所有的consumer的rebalance
    2, Split Brain

    每个consumer分别单独通过Zookeeper判断哪些partition down了,那么不同consumer从Zookeeper“看”到的view就可能不一样,这就会造成错误的reblance尝试。而且有可能所有的consumer都认为rebalance已经完成了,但实际上可能并非如此。

      根据Kafka官方文档,Kafka作者正在考虑在还未发布的0.9.x版本中使用中心协调器(coordinator)。大体思想是选举出一个broker作为coordinator,由它watch Zookeeper,从而判断是否有partition或者consumer的增减,然后生成rebalance命令,并检查是否这些rebalance在所有相关的consumer中被执行成功,如果不成功则重试,若成功则认为此次rebalance成功(这个过程跟replication controller非常类似,所以我很奇怪为什么当初设计replication controller时没有使用类似方式来解决consumer rebalance的问题)。流程如下:

    这里写图片描述