天天看點

如何決定kafka叢集中話題的分區的數量

    如何決定kafka叢集中topic,partition的數量,這是許多kafka使用者經常遇到的問題。本文列舉闡述幾個重要的決定因素,以提供一些參考。

分區多吞吐量更高      

    一個話題topic的各個分區partiton之間是并行的。在producer和broker方面,寫不同的分區是完全并行的。是以一些昂貴的操作比如壓縮,可以獲得更多的資源,因為有多個程序。在consumer方面,一個分區的資料可以由一個consumer線程在拉去資料。分區多,并行的consumer(同一個消費組)也可以多。是以通常,分區越多吞吐量越高。     基于吞吐量可以獲得一個粗略的計算公式。先測量得到在隻有一個分區的情況下,Producer的吞吐量(P)和Consumer的吞吐量(C)。那如果總的目标吞吐量是T的話,max(T/P,T/C)就是需要的最小分區數。在單分區的情況下,Producer的吞吐量可以通過一些配置參數,比如bath的大小、副本的數量、壓縮格式、ack類型來測得。而Consumer的吞吐量通常取決于應用程式處理每一天消息邏輯。這些都是需要切合實際測量。     随着時間推移資料量的增長可能會需要增加分區。有一點需要注意的是,Producer者釋出消息通過key取哈希後映射分發到一個指定的分區,當分區數發生變化後,會帶來key和分區映射關系發生變化。可能某些應用程式依賴key和分區映射關系,映射關系變化了,程式就需要做相應的調整。為了避免這種key和分區關系帶來的應用程式修改。是以在分區的時候盡量提前考慮,未來一年或兩年的對分區資料量的要求。    除了吞吐量,還有一些其他的因素,在定分區的數目時是值得考慮的。在某些情況下,太多的分區也可能會産生負面影響。

分區多需要的打開的檔案句柄也多      

    每個分區都映射到broker上的一個目錄,每個log片段都會有兩個檔案(一個是索引檔案,另一個是實際的資料檔案)。分區越多所需要的檔案句柄也就越多,可以通過配置作業系統的參數增加打開檔案句柄數。

分區多增加了不可用風險      

    kafka支援主備複制,具備更高的可用性和持久性。一個分區(partition)可以有多個副本,這些副本儲存在不同的broker上。每個分區的副本中都會有一個作為Leader。當一個broker失敗時,Leader在這台broker上的分區都會變得不可用,kafka會自動移除Leader,再其他副本中選一個作為新的Leader。Producer和Consumer都隻會與Leader相連。

    一般情況下,當一個broker被正常關機時,controller主動地将Leader從正在關機的broker上移除。移動一個Leader隻需要幾毫秒。然當broker出現異常導緻關機時,不可用會與分區數成正比。假設一個boker上有2000個分區,每個分區有2個副本,那這樣一個boker大約有1000個Leader,當boker異常當機,會同時有1000個分區變得不可用。假設恢複一個分區需要5ms,1000個分區就要5s。

    分區越多,在broker異常當機的情況,恢複所需時間會越長,不可用風險會增加。

分區多會增加點到點的延遲      

    這個延遲需要展現在兩個boker間主備資料同步。在預設情況下,兩個boker隻有一個線程負責資料的複制。

    根據經驗,每個boker上的分區限制在100*b*r内(b指叢集内boker的數量,r指副本數量)。

分區多會增加用戶端的記憶體消耗      

    kafka0.8.2後有個比較好的特色,新的Producer可以允許使用者設定一個緩沖區,緩存一定量的資料。當緩沖區資料到達設定量或者到時間,資料會從緩存區删除發往broker。如果分區很多,每個分區都緩存一定量的資料量在緩沖區,很可能會占用大量的記憶體,甚至超過系統記憶體。     Consumer也存在同樣的問題,會從每個分區拉一批資料回來,分區越多,所需記憶體也就越大。     根據經驗,應該給每個分區配置設定至少幾十KB的記憶體。

總結      

     在通常情況下,增加分區可以提供kafka叢集的吞吐量。然而,也應該意識到叢集的總分區數或是單台伺服器上的分區數過多,會增加不可用及延遲的風險。

     http://www.confluent.io/blog/how-to-choose-the-number-of-topicspartitions-in-a-kafka-cluster/