Kafka的分區策略

原文鏈接:https://blog.csdn.net/weixin_41928342/article/details/80880443

    在kafka中,每個topic一般會有很多個Partitions。爲了使我們能夠及時的消費消息!  我們也可能啓動多個Consumer去消費分區,而每個Consumer同樣會啓動一個或者是多個streams去分別消費Topic裏面的數據。我們又知道,在Kafka中存在着Consumer Group的概念,也就是在group.id 一樣的Consumer,這些Consumer屬於同一個Consumer Group,在組內所有消費者協調在一起來消費訂閱主題(subscribed topics)的所有分區(partition),當然消費者在消費的時候也是有規則限定的,這個規則就是:每個分區只能被同一個消費組內的一個consumer來消費。也就是!同一個消費組裏面的consumer一次不能夠去消費同一個Topic的Partition。  那麼問題來了,同一個Consumer Group裏面的Consumer是如何知道該去消費哪些分區裏面的數據呢!?

    

    就像上面圖示, Consumer 1 爲什麼消費的是Partition0 和Partition2呢??而不是消費的Partition0和Partition3呢?或者是其他呢!?這就涉及到Kafka內部分配策略(Partition Assignment Strategy)!

    說到Kafka分區分配策略,就是它的內部的默認的分區分配策略:Range 和 RoundRobin(輪詢)。當下面的事情發生的時候,Kafka將會進行一次分區分配。

        1、當同一個Consumer Group 內新增消費者。(消費者層面發生改動)

        2、消費者離開當前所屬的Consumer Group,包括Shuts down(關閉、停工)或者是crashes(崩潰)。(消費者層面發生改動)

        3、就是消費者訂閱的主題新增的分區的時候!

將分區的所有權從一個消費者移到另一個消費者成爲重新平衡(rebalance),如何rebalance就涉及到分區分配策略。

我們假設有一個名爲Top1的主題,它有十個分區,然後我們有兩個消費者(C1、C2)來消費這十個分區裏面的數據,而且C1的num.streams=1,C2的num.streams=2。

下面介紹第一個默認的分區策略:Range  Startegy(根據範圍消費)

    Range startegy是對每個主題而言的 , 首先對同一個主題裏面的分區按照序號進行排序,並對消費者按照字母進行排序。在對十個分區排序的話是0-9;消費者線程排完序是C1-0,C2-0,C2-1。然後用partitions的總數除以消費者的總數來決定每個消費者線程消費幾個分區。如果有餘數,那麼前面的幾個消費者線程將會多消費一個分區。在我們的例子裏面,我們有十個分區,三個消費者線程,10/3=3---1,那麼消費者線程C1-0    將會多消費一個分區,所以最後分區分配的結構看起來是這樣的:

    C1-0將消費0,1,2,3分區

    C2-0將消費4,5,6分區

    C2-1將消費7,8,9分區

如果有第十一個分區的話,那麼分區是這樣的

    C1-0將消費0,1,2,3分區
    C2-0將消費4,5,6,7分區

    C2-1將消費8,9,10分區

如果我們有2個主題(T1和T2),分別都有十個分區,那麼最後的分配結果是:

     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消費者線程比其他消費者線程多消費了兩個分區,這就是Range Strategy的一個明顯的弊端。 當分區很多的時候,會有個別的線程壓力巨大!


下面介紹的是第二個默認的分區策略:RoundRobin strategy(輪詢的消費策略)

在使用RoundRobin Starategy的時候我們必須滿足兩個條件:

    1、同一個consumer Group裏面的所有消費者的num.streams必須相等;

    2、每個消費者訂閱的 主題必須相同

在這裏我們假設2個消費者的num.streams=2.  RoundRobin starategy的工作原理: 將所有主題的分區組成TopicAndPartition列表,然後對TopAndPartition列表按照hashcode進行排序,下面是代碼!



最後按照round-robin風格將分區分別分配給不同的消費者線程。

在我們的例子中,假如按照hashcode排序完的topic-partition組依次爲T1-5,T1-3,T1-0.T1-8.T1-2,T1-1,T1-4,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分區;

遺憾的是,目前我們還不能自定義分區分配策略,只能通過partition.assignment.strategy參數選擇range或roundrobin。  partition.assignment.strategy參數默認的值是range。

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