分組消費的再平衡策略

從kafka消費消息,kafka客戶端提供兩種模式: 分區消費,分組消費。

分區消費對應的就是我們的DirectKafkaInputDStream

分組消費對應的就是我們的KafkaInputDStream

消費者數目跟分區數目的關係:

1),一個消費者可以消費一個到全部分區數據

2),分組消費,同一個分組內所有消費者消費一份完整的數據,此時一個分區數據只能被一個消費者消費,而一個消費者可以消費多個分區數據

3),同一個消費組內,消費者數目大於分區數目後,消費者會有空餘=分區數-消費者數

 

二,分組消費的再平衡策略

當一個group中,有consumer加入或者離開時,會觸發partitions均衡partition.assignment.strategy,決定了partition分配給消費者的分配策略,有兩種分配策略:

1,org.apache.kafka.clients.consumer.RangeAssignor

默認採用的是這種再平衡方式,這種方式分配只是針對消費者訂閱的topic的單個topic所有分區再分配,Consumer Rebalance的算法如下:

1),將目標Topic下的所有Partirtion排序,存於TP

2),對某Consumer Group下所有Consumer按照名字根據字典排序,存於CG,第i個Consumer記爲Ci

3),N=size(TP)/size(CG)

4),R=size(TP)%size(CG)

5),Ci獲取的分區起始位置=N*i+min(i,R)

6),Ci獲取的分區總數=N+(if (i+ 1 > R) 0 else 1)

2,org.apache.kafka.clients.consumer.RoundRobinAssignor

這種分配策略是針對消費者消費的所有topic的所有分區進行分配。當有新的消費者加入或者有消費者退出,就會觸發rebalance。這種方式有兩點要求

A),在實例化每個消費者時給每個topic指定相同的流數

B),每個消費者實例訂閱的topic必須相同

Map<String, Integer> topicCountMap = new HashMap<String, Integer>();

topicCountMap.put(topic, new Integer(1));

Map<String, List<KafkaStream<byte[], byte[]>>> consumerMap = consumer.createMessageStreams(topicCountMap);

其中,topic對應的value就是流數目。對應的kafka源碼是在

在kafka.consumer.ZookeeperConsumerConnector的consume方法裏,根據這個參數構建了相同數目的KafkaStream。

這種策略的具體分配步驟:

1),對所有topic的所有分區按照topic+partition轉string之後的hash進行排序

2),對消費者按字典進行排序

3),然後輪訓的方式將分區分配給消費者

 

3,舉例對比

舉個例子,比如有兩個消費者(c0,c1),兩個topic(t0,t1),每個topic有三個分區p(0-2),

那麼採用RangeAssignor,結果爲:

* C0: [t0p0, t0p1, t1p0, t1p1]

* C1: [t0p2, t1p2]

採用RoundRobinAssignor,結果爲:

* C0: [t0p0, t0p2, t1p1]

* C1: [t0p1, t1p0, t1p2]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章