Kafka的分割槽分配策略

2021-10-13 07:31:28 字數 3355 閱讀 8385

用過 kafka 的同學應該都知道,每個 topic 一般會有很多個 partitions。為了使得我們能夠及時消費訊息,我們也可能會啟動多個 consumer 去消費,而每個 consumer 又會啟動乙個或多個streams去分別消費 topic 對應分割槽中的資料。我們又知道,kafka 存在 consumer group 的概念,也就是group.id一樣的 consumer,這些 consumer 屬於同乙個consumer group,組內的所有消費者協調在一起來消費訂閱主題(subscribed topics)的所有分割槽(partition)。當然,每個分割槽只能由同乙個消費組內的乙個consumer來消費。那麼問題來了,同乙個 consumer group 裡面的 consumer 是如何知道該消費哪些分割槽裡面的資料呢?

將所有broker(n個)和partition排序

將第i個partition分配到第(i mode n)個broker上

當key為空時,訊息隨機傳送到各個分割槽(各個版本會有不同,有的是採用輪詢的方式,有的是隨機,有的是一定時間內只傳送給固定partition,隔一段時間後隨機換乙個)用key的ha』sh值對partion個數取模,決定要把訊息傳送到哪個partition上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策略有兩個前提條件必須滿足:

所以這裡假設前面提到的2個消費者的num.streams = 2。roundrobin策略的工作原理:將所有主題的分割槽組成 topicandpartition 列表,然後對 topicandpartition 列表按照 hashcode 進行排序,這裡文字可能說不清,看下面的**應該會明白:(其實就是按分割槽名hash排序後平均分配給每乙個消費者的執行緒)

valalltopicpartitions=ctx.partitionsfortopic.flatmap )

}.toseq.sortwith((topicpartition1, topicpartition2)=> )

最後按照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。

1.同乙個consumer group內新增或減少consumer

2.topic分割槽發生變化

kafka提供了乙個角色coordinator來執行。當consumer group的第乙個consumer啟動的時候,他會向kafka集群中的任意一台broker傳送groupcoordinatorrequest請求,broker會返回乙個負載最小的broker設定為coordinator,之後該group的所有成員都會和coordinator進行協調通訊

整個rebalance分為兩個過程jiongroupsysncjion

joingroup過程

在這一步中,所有的成員都會向coordinator傳送jiongroup請求,請求內容包括group_id,member_id.protocol_metadata等,coordinator會從中選出乙個consumer作為leader,並且把組成員資訊和訂閱訊息,leader資訊,rebanlance的版本資訊傳送給consumer

synchronizing group state階段

組成員向coordinator傳送sysngrouprequet請求,但是只有leader會傳送分割槽分配的方案(分割槽分配的方案其實是在消費者確定的),當coordinator收到leader傳送的分割槽分配方案後,會通過sysngroupresponse把方案同步到各個consumer中

**: 

kafka的分割槽分配策略

將所有broker n個 和partition排序 將第i個partition分配到第 i mode n 個broker上 當key為空時,訊息隨機傳送到各個分割槽 各個版本會有不同,有的是採用輪詢的方式,有的是隨機,有的是一定時間內只傳送給固定partition,隔一段時間後隨機換乙個 用key的...

詳解Kafka分割槽分配策略

前言 乙個consumer group中有多個consumer,乙個topic有多個partition,所以必然會涉及到partition的分配問題,即確定那個partition由哪個consumer來消費。kafka有兩種分配策略,一是roundrobin,二是range 1.roundrobin...

kafka 訊息的分割槽分配策略

訊息的消費原理 觸發分割槽分配策略的條件 topic 在kafka 中,topic是乙個儲存訊息的邏輯概念,可以認為是乙個訊息的集合。每條訊息傳送到 kafka 集群的訊息都有乙個類別。每個topic可以有多個生產者向他傳送訊息,也可以有多個消費者去消費訊息 partition 每個topic 可以...