kafka分區----分區如何分配到broker----生產者分區策略----消費者消費策略


1.分區的一些基本概念規則

  1. 每個topic都可以被划分成一個或者多個分區(至少有一個分區),它是topic物理上的分組,在創建topic的時候指定
  2. 一個Partition只對應一個Broker,一個Broker可以管理多個Partition。
  3. 在一個分區內消息是順序的,在不同的分區之間,kafka並不保證消息的順序
    • 同一個主題下,不同分區所包含的內容是不同的,每個消息被添加到分區當中時,會被分配一個偏移量(offset),它是消息在分區當中的唯一編號,kafka是通過offset來確保一個分區內的消息順序的,offset的順序並不跨越分區。
    • 在需要嚴格保證消息的消費順序的場景下,需要將partition數目設為1

2.分區下的Leader和Follower

  1. 每個分區選一個server節點作Leader,(0個或多個)server節點做Follower。
  2. 每個分區有且僅有一個Leader,Leader是負責當前數據讀寫的Partition;有(0個或多個)Follower跟隨Leader,保持數據同步
  3. Leadre失效,會從Follower中選舉一個新的Leader
  4. Follower掛掉、卡住或者同步太慢,Leader會把Follower刪除,在新建個follower
  5. Leader和Follower跨節點同步,達到一種選舉方式,若是在一個broker上同步沒意義;每個服務器都能作為分區的一個Leader和其他分區的flowers,因此kafka是一個去中心化的集群,能被很好平衡(雖然也可以一個server上又多個leader,但是壓力會大)

3.分區如何分配到broker

  1. 網上查到的分配策略如下
    • 將所有的broker和partition排序;
    • 將第i個partition分配到第(i mode n)個broker上,這個Partition的第一個Replica存在於這個分配的Broker上,並且會作為partition的優先副本
    • 將第i個partition的j個副本,放到第((i+j) mode n)個broker上
  2. 上述做法會有問題,每一個topic的分區0都會被分配在broker 0上,第1個分區都分配到broker 1上。直到partition的id超過broker的數量后開始重復在輪詢,這樣會導致分區更多的在前幾個broker上,這樣前面的機器的壓力比后面的機器壓力更大,反而會造成負載不均衡。同時我們也可以做實驗得到證明,真實的分配方法並不是上面這樣。
  3. 實際上在Kafka集群中,每一個Broker都有均等分配Partition的Leader機會,kafka是先隨機挑選一個broker放置分區0,然后再按順序放置其他分區,副本也是一樣的情況。第一個放置的分區副本一般都是 Leader,其余的都是 Follow 副本。

4.Segment

  1. 由於生產者生產的消息會不斷追加到log文件末尾,為防止log文件過大導致數據定位效率低下,kafka采取了分片和索引機制。將每個partition分為多個segment file,每個segment file存着message,segment由兩部分(.log數據文件 .index索引文件)組成,並且一一對應
  2. 目錄和file都是物理存儲於磁盤,但是kafka不支持隨機讀寫,只支持順序讀寫,有效提高磁盤利用率,而且順序讀寫速度超過內存讀寫速度,所以效率很高
  3. partion全局的第一個segment從0開始,后續每個segment文件名為上一個segment文件最后一條消息的offset值
  4. ".log"數據文件
    • offset在parition(分區)內的每條消息都有一個有序的id號,這個id號被稱為偏移(offset),它可以唯一確定每條消息在parition(分區)內的位置。即offset表示partiion的第多少message
    • MessageSize表示消息內容data的大小
    • data為Message的具體內容
  5. ".index"索引文件
    • 采取稀疏索引的方式,減少了索引文件的大小,相對於稠密索引節約了存儲空間,但是查找起來更費時間
    • 索引包含兩個部分,分別為相對offset和position
  6. 消息的查找流程
    • 通過offset定位數據信息在哪個文件(.log,.index)
    • 找到文件后,在根據offset和文件名計算相對偏移量,可以找到index中查找到對應position????還需要試驗下

5.生產者分區策略

  1. 每一條下消息ProducerRecord由主題名稱、可選的分區號、可選的鍵和值組成
  2. 分區策略
    • 如果消息ProducerRecord中指定了有效partition字段,發送記錄使用該partition
    • 如果消息ProducerRecord中沒有指定partition字段
      • 但指定key,則將使用key進行hash采用MurmurHash2算法,具備高運算性能及低碰撞率)選擇一個分區
      • 且沒有key,則將以輪詢的方式分配一個分區,常說的“round-robin”算法
    • 注意:如果key不為null,那么hash計算得到的分區號會是所有分區中的任意一個;如果key為null並且有可用分區,那么計算得到的分區號僅為可用分區中的任意一個
  3. 自己定義分區策略
    • 隨機分區
      • 創建一個類,並繼承partitioner,改寫partition
      • 再修改配置文件partitioner.class=XXX._RandomPartitioner,啟動即可
      • 或者prop.put("partition.class",XXX._RandomPartitioner.class)
      public class _RandomPartitioner implements Partitioner{
      	public int partition(String topic, Object key, byte[] keyBytes,
                           Object value, byte[] valueBytes, Cluster cluster){
      			//獲取總的分區數
      			 Integer partitionNum = cluster.partitionsForTopic(topic);
      			 // 隨機策略
      			 int i = random.nextInt(partitionNum)
      			 return i
      		}
      }
      
    • hash分區(個人寫的話可以模擬下:hash算完取絕對值,在取模)
    • 輪詢分區
    • 分組分區
提高kafka並行度,其實就是提高kafka topic分區的個數,分區個數提高了,同一時間同一消費組內可以有的消費者可以更多,消費能力增強。一般分區和消費組內的消費者保持對應


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM