Kafka 中各种分配策略

分区在集群中的分配策略

  1. 将所有broker(n个)和partition排序
  2. 将第i个Partition分配到第(i mode n)个broker上

      

Producer 把消息发送给对应分区策略

  1. 当key和partition都为空时,消息随机发送到各个分区(各个版本会有不同,有的是采用轮询的方式,有的是随机,有的是一定时间内只发送给固定partition,隔一段时间后随机换一个)
  2. 当partition空,单key不为空时,用key的ha’sh值对partion个数取模,决定要把消息发送到哪个partition上
  3. 当key和partition都不为空时,只会根据partition发送到对应的partition上
  4. 当key为空、partition不为空时,根据partition发送到指定的partition上

 

消费者分区分配策略

1.RangePartitionAssignor(默认):

       针对每一个topic:

          n = 分区数/消费者数量

          m = 分区数%消费者数量

         前m个消费者每个分配n+1个分区,后面的 (消费者数量-m)个消费者每个分配n个分区

假如有10个分区,3个消费者,把分区按照序号排列0,1,2,3,4,5,6,7,8,9;消费者为C1,C2,C3,那么用分区数除以消费者数来决定每个Consumer消费几个Partition,除不尽的前面几个消费者将会多消费一个 
最后分配结果如下

C1:0,1,2,3 
C2:4,5,6 
C3:7,8,9

如果有11个分区将会是:

C1:0,1,2,3 
C2:4,5,6,7 
C3:8,9,10

假如我们有两个主题T1,T2,分别有10个分区,最后的分配结果将会是这样:

C1:T1(0,1,2,3) T2(0,1,2,3) 
C2:T1(4,5,6) T2(4,5,6) 
C3:T1(7,8,9) T2(7,8,9)

在这种情况下,C1多消费了两个分区

2.RoundRobinAssignor

将所有的Topic和Partition按照字典顺序排序,然后对每个Consumer进行轮询分配

roundrobin策略针对于全局所有的topic和消费者,分配步骤如下: 
1. 消费者按照字典排序,例如C0, C1, C2… …,并构造环形迭代器。 
2. topic名称按照字典排序,并得到每个topic的所有分区,从而得到所有分区集合。 
3. 遍历第2步所有分区集合,同时轮询消费者。 
4. 如果轮询到的消费者订阅的topic不包括当前遍历的分区所属topic,则跳过;否则分配给当前消费者,并继续第3步。

所以对于某个topic来说: 
如果有5个分区(P0, P1, P2, P3, P4),且订阅这个topic的消费者组有2个消费者(C0, C1)。那么P0, P2, P4将被C0消费,P1, P3将被C1消费。

roundrobin策略如下图所示: 

roundrobinç­ç¥

如图所示: 
3个Topic:T0(3个分区0, 1, 2), T1(两个分区0, 1), T2(4个分区0, 1, 2, 3); 
3个consumer: C0订阅了[T0, T1], C1订阅了[T1, T2], C2订阅了[T2, T0];

roundrobin结果分配结果如下: 
T0-P0分配给C0,T0-P1分配给C2,T0-P2分配给C0, 
T1-P0分配给C1,T1-P1分配给C0, 
T2-P0分配给C1,T2-P1分配给C2,T2-P2分配给C1,T0-P3分配给C2;

推算过程: 
分区T0-P0,消费者C0,C0订阅了这个分区所在Topic即T0,所以T0-P0分配给C0; 
轮询到下一个分区T0-P1和下一个消费者C1; 
分区T0-P1,消费者C1,C1没有订阅T0,取下一个消费者C2,C2订阅了T0,所以T0-P1分配给C2; 
轮询到下一个分区T0-P2和下一个消费者C0; 
分区T0-P2,消费者C0,C0订阅了T0,所以T0-P2分配给C0; 
轮询到下一个分区T1-P0和下一个消费者C1; 
分区T1-P0,消费者C1,C1订阅T1,所以T1-P0分配给C1; 
以此类推即可。

 

3.自定义分配策略:实现AbstractPartitionAssignor类的assign()方法

 

Replication副本分配算法例如以下:

将全部N Broker和待分配的i个Partition排序. 
将第i个Partition分配到第(i mod n)个Broker上. 
将第i个Partition的第j个副本分配到第((i + j) mod n)个Broker上.

 

Rebalance的执行

Reblance本质上是一种协议,规定了一个Consumer Group下的所有的Consumer如何达成一致来分配订阅Topic的每个Partition。比如某个group下有5个consumer,它订阅了一个具有10个分区的topic。正常情况下,Kafka平均会为每个consumer分配2个分区。这个分配的过程就叫rebalance。

Rebalance的触发条件:

1.有新的消费者加入Consumer Group

2.有消费者下线,可能由于长时间未向GroupCoordinator(协调者)发送心跳,GroupCoordinator会认为其已下线

3.有消费者主动退出Consumer Group

4.订阅的topic分区出现变化

5.调用unsubscribe()取消对某Topic的订阅

即Consumer或者Topic自身发生变化时,会触发Rebalance。
 


更多精彩内容