kafka分區數和吞吐量的關係
- 2019 年 12 月 27 日
- 筆記

分區(partition)概念
要講 kafka 分區數和吞吐量的關係,首先得理解什麼是分區(partition)。

Partition
是作用於具體的Topic
而已的,而不是一個獨立的概念。Partition
能水平擴展客戶端的讀寫性能,是高吞吐量的保障。通俗的講,Partition
就是一塊保存具體數據的空間,本質就是磁盤上存放數據的文件夾,所以Partition
是不能跨Broker
存在的,也不能在同一個Broker
上跨磁盤。對於一個Topic
,可以根據需要設定Partition
的個數。數據持久化時,每條消息都是根據一定的分區規則路由到對應的Partition
中,並append
在log
文件的尾部(這一點類似於HDFS
),如上圖;在同一個Partition
中消息是順序寫入的且始終保持有序性;但是不同Partition
之間不能保證消息的有序性(高吞吐量的保障)。kafka
就是通過使用分區的設計將topic
的消息打散到多個分區分佈保存在不同的broker
上,實現了producer
和consumer
消息處理的高吞吐量。
吞吐量關係

在kafka
中,Partition
並不是最小的數據存儲單元。Partition
下還可以細分成Segment
,每個Partition
是由一個或多個Segment
組成。但patition
是kafka
並行操作的最小單元。在producer
和broker
端,向每一個分區寫入數據是可以完全並行化的,此時,可以通過加大硬件資源的利用率來提升系統的吞吐量,例如對數據進行壓縮。在consumer
端,kafka
只允許單個partition
的數據同時被一個consumer
線程消費。因此,在consumer
端,每一個Consumer Group
內部的consumer
並行度完全依賴於被消費的分區數量。因此,通常情況下,在一個 Kafka 集群中,partition
的數量越多,意味着可以到達的吞吐量越大。
我們可以粗略地通過吞吐量來計算kafka
集群的分區數量。假設對於單個partition
,producer
端的可達吞吐量為 p,Consumer
端的可達吞吐量為 c,期望的目標吞吐量為 t,那麼集群所需要的partition
數量至少為max(t/p,t/c)
。在producer
端,單個分區的吞吐量大小會受到批量大小、數據壓縮方法、確認類型(同步/異步)、複製因子等配置參數的影響。經過測試,在producer
端,單個partition
的吞吐量通常是在 10MB/s 左右。在consumer
端,單個partition
的吞吐量依賴於consumer
端每個消息的應用邏輯處理速度。因此,我們需要對consumer
端的吞吐量進行測量。
分區擴展
雖然隨着時間的推移,我們能夠對分區的數量進行添加,但是對於基於Key
來生成的這一類消息不太一樣。當producer
向kafka
寫入基於key
的消息時,kafka
通過key
的hash
值來確定消息需要寫入哪個具體的分區。通過這樣的方案,kafka
能夠確保相同key
值的數據可以寫入同一個partition
。kafka
的這一能力對於一部分順序要求的業務應用是極為重要的,例如對於同一個key
的所有消息,consumer
需要按消息的順序進行有序消費。如果partition
的數量發生改變,那麼上面的有序性保證將不復存在。為了避免上述情況發生,通常的解決辦法是多分配一些分區,以滿足未來的需求。
此外,我們還可以基於當前的業務吞吐量為kafka
集群分配較小的broker
數量,隨着業務增長,再向集群中增加更多的broker
,然後將適當比例的partition
遷移到新增加的broker
中去(遷移可以參考我之前的文章)。通過這樣的方法,可以在滿足各種應用場景(包括基於key
消息的場景)的情況下,保持業務吞吐量的擴展性。
在規劃分區數時,除了吞吐量,還有一些其他因素值得考慮,後續再聊。
