Kafka分割槽分配策略(Partition Assignment Strategy)
Kafka分割槽分配策略(Partition Assignment Strategy)
參考:
https://www.iteblog.com/archives/2209.html
1.問題
2.Range Strategy
3.RoundRobin Strategy
問題
用過Kafka 的同學用過都知道,每個 Topic 一般會有很多個 partitions。為了使得我們能夠及時消費訊息,我們也可能會啟動多個 Consumer 去消費,而每個 Consumer 又會啟動一個或多個streams去分別消費 Topic 裡面的資料。我們又知道,Kafka 存在 Consumer Group 的概念,也是 group.id 一樣的 Consumer,這些 Consumer 屬於同一個Consumer Group,組內的所有消費者協調在一起來消費訂閱主題(subscribed topics)的所有分割槽(partition)。當然,每個分割槽只能由同一個消費組內的一個consumer來消費。那麼問題來了,同一個 Consumer Group 裡面的 Consumer 是如何知道該消費哪些分割槽裡面的資料呢?
如上圖,Consumer1 為啥消費的是 Partition0 和 Partition2,而不是 Partition0 和 Partition3?這就涉及到 Kafka 內部分割槽分配策略(Partition Assignment Strategy)了。
在Kafka 內部存在兩種預設的分割槽分配策略:Range 和 RoundRobin。當以下事件發生時,Kafka 將會進行一次分割槽分配:
同一個Consumer Group 內新增消費者
消費者離開當前所屬的Consumer Group,包括shuts down 或 crashes
訂閱的主題新增分割槽
將分割槽的所有權從一個消費者移到另一個消費者稱為重新平衡(rebalance),如何rebalance就涉及到本文提到的分割槽分配策略。下面我們將詳細介紹 Kafka 內建的兩種分割槽分配策略。本文假設我們有個名為 T1 的主題,其包含了10個分割槽,然後我們有兩個消費者(C1,C2)來消費這10個分割槽裡面的資料,而且 C1 的 num.streams = 1,C2 的 num.streams = 2。
Range strategy
Range策略是對每個主題而言的,首先對同一個主題裡面的分割槽按照序號進行排序,並對消費者按照字母順序進行排序。在我們的例子裡面,排完序的分割槽將會是0, 1, 2, 3, 4, 5, 6, 7, 8, 9;消費者執行緒排完序將會是C1-0, C2-0, C2-1。然後將partitions的個數除於消費者執行緒的總數來決定每個消費者執行緒消費幾個分割槽。如果除不盡,那麼前面幾個消費者執行緒將會多消費一個分割槽。在我們的例子裡面,我們有10個分割槽,3個消費者執行緒, 10 / 3 = 3,而且除不盡,那麼消費者執行緒 C1-0 將會多消費一個分割槽,所以最後分割槽分配的結果看起來是這樣的:
C1-0 將消費 0, 1, 2, 3 分割槽
C2-0 將消費 4, 5, 6 分割槽
C2-1 將消費 7, 8, 9 分割槽
假如我們有11個分割槽,那麼最後分割槽分配的結果看起來是這樣的:
C1-0 將消費 0, 1, 2, 3 分割槽
C2-0 將消費 4, 5, 6, 7 分割槽
C2-1 將消費 8, 9, 10 分割槽
假如我們有2個主題(T1和T2),分別有10個分割槽,那麼最後分割槽分配的結果看起來是這樣的:
C1-0 將消費 T1主題的 0, 1, 2, 3 分割槽以及 T2主題的 0, 1, 2, 3分割槽
C2-0 將消費 T1主題的 4, 5, 6 分割槽以及 T2主題的 4, 5, 6分割槽
C2-1 將消費 T1主題的 7, 8, 9 分割槽以及 T2主題的 7, 8, 9分割槽
可以看出,C1-0 消費者執行緒比其他消費者執行緒多消費了2個分割槽,這就是Range strategy的一個很明顯的弊端。
RoundRobin strategy
使用RoundRobin策略有兩個前提條件必須滿足:
同一個Consumer Group裡面的所有消費者的num.streams必須相等;
每個消費者訂閱的主題必須相同。
所以這裡假設前面提到的2個消費者的num.streams = 2。RoundRobin策略的工作原理:將所有主題的分割槽組成 TopicAndPartition 列表,然後對 TopicAndPartition 列表按照 hashCode 進行排序,這裡文字可能說不清,看下面的程式碼應該會明白:
<pre>
val allTopicPartitions = ctx.partitionsForTopic.flatMap { case(topic, partitions)=>
info("Consumer %s rebalancing the following partitions for topic %s: %s"
.format(ctx.consumerId, topic, partitions))
partitions.map(partition => {
TopicAndPartition(topic, partition)
})
}.toSeq.sortWith((topicPartition1, topicPartition2) => {
/*
Randomize the order by taking the hashcode to reduce the likelihood of all partitions of a given topic ending
up on one consumer (if it has a high enough stream count).
*/
topicPartition1.toString.hashCode < topicPartition2.toString.hashCode
})
</pre>
最後按照
round-robin風格將分割槽分別分配給不同的消費者執行緒。
在我們的例子裡面,加入按照
hashCode 排序完的topic-partitions組依次為T1-5, T1-3, T1-0, T1-8, T1-2, T1-1, T1-4, T1-7, T1-6, T1-9,我們的消費者執行緒排序為C1-0, C1-1, C2-0, C2-1,最後分割槽分配的結果為:
C1-0 將消費 T1-5, T1-2, T1-6 分割槽;
C1-1 將消費 T1-3, T1-1, T1-9 分割槽;
C2-0 將消費 T1-0, T1-4 分割槽;
C2-1 將消費 T1-8, T1-7 分割槽;
多個主題的分割槽分配和單個主題類似,這裡就不在介紹了。
根據上面的詳細介紹相信大家已經對Kafka的分割槽分配策略原理很清楚了。不過遺憾的是,目前我們還不能自定義分割槽分配策略,只能通過partition.assignment.strategy引數選擇range 或 roundrobin。partition.assignment.strategy引數預設的值是range。
相關文章
- 分割槽Partition
- 分割槽partition知識點
- Kafka 分割槽Kafka
- Spark學習——分割槽Partition數Spark
- Oracle Partition 分割槽詳細總結Oracle
- 分割槽函式Partition By的基本用法函式
- Flink的分割槽策略
- Kafka - 自定義分割槽器Kafka
- 分割槽函式partition by的基本用法【轉載】函式
- Hive和Spark分割槽策略HiveSpark
- Oracle查詢Interval partition分割槽表內資料Oracle
- 詳細解析kafka之kafka分割槽和副本Kafka
- 使用parted建立大分割槽時 mkpart Warning: The resulting partition is not properly
- 幹趴面試官系列 | 請你簡述一下Kafka中的分割槽分配面試Kafka
- Kafka 消費組消費者分配策略Kafka
- MySQL全面瓦解29:使用Partition功能實現水平分割槽MySql
- 【kafka】-分割槽-消費端負載均衡Kafka負載
- 解密Kafka主題的分割槽策略:提升實時資料處理的關鍵解密Kafka
- 作業系統 『動態(可變)分割槽分配』作業系統
- kafka Poll輪詢機制與消費者組的重平衡分割槽策略剖析-kafka 商業環境實戰Kafka
- kafka指定key進行分割槽遇到的問題Kafka
- Partition|Disk Utility 如何分割磁碟
- AppBoxFuture: 大資料表分割槽的3種策略APP大資料
- Linux分割槽方案、分割槽建議Linux
- 如何為Kafka叢集確定合適的分割槽數以及分割槽數過多帶來的弊端Kafka
- filebeat將日誌傳送到kafka不同分割槽的方法Kafka
- Laravel Query Builder 複雜查詢案例:子查詢實現分割槽查詢 partition byLaravelUI
- oracle分割槽表和分割槽表exchangeOracle
- PostgreSQL/LightDB 分割槽表之分割槽裁剪SQL
- Linux 分割槽擴容(根分割槽擴容,SWAP 分割槽擴容,掛載新分割槽為目錄)Linux
- Oracle分割槽表基礎運維-07增加分割槽(2 HASH分割槽)Oracle運維
- 策略模式(Strategy)模式
- oracle分割槽表和非分割槽表exchangeOracle
- 非分割槽錶轉換成分割槽表
- [oracle] expdp 匯出分割槽表的分割槽Oracle
- Oracle分割槽表基礎運維-07增加分割槽(1範圍分割槽)Oracle運維
- openGauss 分割槽
- mysql 分割槽MySql