如何選擇一個Kafka叢集中的主題分割槽的數量

喜馬拉雅以南發表於2020-10-30


Kafka叢集中分割槽應該設定多少比較合適,這是一個面對眾多開發者共同的難題,這篇文章的目標就是來解釋一些重要的因素,同時會提供一些簡單的公式。

更多的分割槽可使吞吐量更大

首先我們要有個認知,那就是分割槽(partition)是Kafka中的併發單位。
從生產者和Broker層面來說,寫入訊息到不同的分割槽是一種完全的併發行為,所以例如壓縮等重量級操作,可以使用更多的硬體資源來解決。
在消費者層面,Kafka總是將單個分割槽的資料交由一個消費執行緒進行消費,因此,在消費者側的併發程度是由消費的分割槽數量約束的。
由上述總結可知,通常情況下在Kafka叢集內,更多的partition能夠獲得更大的吞吐量。

通過如下公式可以根據吞吐量粗略的預估出需要建立多少個分割槽。首先你需要可以獲得單個分割槽的生產量,我們使用字母p表示,消費量用c表示,比如說你的目標吞吐量為t,那麼你則需要至少max(t/p,t/c)個分割槽。每個分割槽吞吐量依賴於生產者的配置,如批處理條數、壓縮編碼、已知的型別。副本因素等等。但是通常一個生產者在基準測試中的表現能達到10MB/sec,消費者的吞吐量取決於應用程式,消費者的速度與每條訊息的處理邏輯相關,因此消費者的消費速度需要你自行進行基準測試。

儘管可以隨著時間不斷增加分割槽數量,但是如果生成帶有key的訊息,則必須注意。 釋出送帶有key的訊息時,Kafka根據key的雜湊確定將訊息對映到哪個分割槽。 這保證了具有相同key的訊息始終被路由到相同的分割槽。對於某些應用程式,此種特性可能很重要,因為每個分割槽內訊息總是被順序遞送的,也就是同一個分割槽那麼消費者可以做到順序消費。如果分割槽數量改變,那麼可能會打破原有的順序消費邏輯,從而這種保證也不再成立。為了避免這種情況,一般採用對分割槽過度分割槽,你可以決定未來一兩年的吞吐量,從而確定分割槽數。一開始你可以只擁有一個基於你當前團兔糧的小型kafka叢集,隨著時間增長,你可以成比例地增加broker到你的現有的及群眾,並將部分已存在的分割槽移動至新的broker中,這個方法在保持你吞吐量增長的同時,不會破壞你在程式中對訊息key的使用。

更多的分割槽需要更多檔案控制程式碼

每個分割槽均會在broker所在的檔案系統中對映一個檔案目錄,在日誌目錄內,每個日誌段將會有個兩個檔案,一個是索引檔案,另一個是實際的資料。當前,在kafka中broker會開啟每個日誌段的索引檔案和資料檔案控制程式碼,因此分割槽越多,則在底層作業系統中配置檔案控制程式碼限制就需要越高。

更多的分割槽增加不可用性

Kafka叢集內部支援副本分片,從而達到高可用和永續性,一個分割槽可以有多個副本,每個都儲存在不同的borker上,副本中一個被指定為leader且其他副本將會成為follower,kafka管理所有的那些副本的複製並確保副本之間的同步,所有的生產者和消費者所傳送的請求均是由leader副本進行服務的,當broker當機,在這個broker上的leader副本將短暫不可用,kafka將會自動移動不可用分割槽的leader角色副本到其他副本上,繼續提供服務。這個處理有kafka的broker中控制角色進行制定,它涉及為ZooKeeper中每個受影響的分割槽讀寫一些後設資料。 當前,對ZooKeeper的操作是在控制器中序列完成的。

更多的分割槽更高的端到端的延遲

在kafka中我們定義,從生產者傳送訊息到消費者準備消費所用的時間為端到端延遲。kafka只會在提交(commit)訊息之後再想消費者傳送訊息,也就是當訊息在所有副本中同步之後才會提交訊息,因此提交一個訊息的花費時間可能是端到端延遲的很大一部分時間。預設情況下,對於只有兩個broker的所有分割槽來說,broker僅僅使用一個單執行緒複製資料到另一個broker的副本中。我們實驗表明,從一個broker複製1000個分割槽到另一個broker會花費大概20ms的時間,這意味著最短就是20ms。

更多的分割槽需要更多的記憶體

相關文章