kafka分區數過多的弊端


 

上篇文章我們了解到,如果一個topic分區越多,理論上整個集群所能達到的吞吐量就越大。那么,分區數越多就越好嗎?顯然不是。今天我們來聊下kafka在分區數過多的情況下,會帶來哪些弊端。

內存開銷

客戶端producer有個參數batch.size默認為16KB。它會為每個分區緩存消息,一旦批次數滿了后,將消息批量發出。一般來說,這個設計是用於提升吞吐性能的。但是由於這個參數是partition級別的,如果分區數越多,這部分緩存所需的內存占用也會越多。假如有10000個分區,按照默認配置,這部分緩存就要占用約157MB的內存。而consumer端呢?拋開拉取數據所需的內存不說,單說線程的開銷。如果還是10000個分區,同時consumer線程數要匹配分區數的話(大部分情況下是最佳的消費吞吐量配置),那么在consumer client就要創建10000個線程,也需要創建大約10000個Socket去獲取分區數據,這里面的線程切換的開銷本身就已經不容小覷了。
服務器端的開銷也不小,如果閱讀kafka源碼的話就會發現,服務器端的很多組件在內存中維護了partition級別的緩存,比如controllerFetcherManager等,因此分區數越多,這種緩存的成本就越大。

文件句柄開銷

每個分區在文件系統上會對應一個目錄,用於存儲維護kafka數據日志。該目錄通常會有3個文件,.log.index.timeindex,對應kafka的日志數據文件和索引文件(老版本kafka沒有timeindex文件)。broker會一直保持打開這3個文件句柄(file handler)。因此,如果分區數越多,所需要保持打開狀態的文件句柄數也就越多,最終可能會突破單台brokerulimit -n的上限。

鏈路延遲

kafka的鏈路延遲也就是producer端發布消息到consumer端接收消息所需要的時間。kafka只有在消息提交之后,才會將消息暴露給消費者,期間消息需要在in-sync副本列表中完成同步復制,這是耗時的主要部分。默認情況下,每個broker從其他broker節點進行數據副本同步時,該節點只會為此分配一個線程,該線程需要完成該broker上所有partition數據的復制。我查到數據顯示,將1000個partition從一個broker到另一個broker所需時間延遲約為20ms,這意味着鏈路延遲至少是20ms。這樣的延遲對於一些實時業務來說可能就有些長了。

SLA

kafka是通過副本機制(replica)提供高可用,來保障SLA的。每個partition都會有多個副本,每個副本分別存在於不同的broker。所有的數據副本中,有一個數據副本被選舉為leader,負責處理producerconsumer請求。其他的數據副本為follower,由Kafka controller負責保證與leader的同步。當leader不可用時,會從follower中重新選出新的leader,這中間會有短暫的不可用時間,雖然大部分情況下可能只是幾毫秒級別。但是假如,一個2節點的kafka集群中存在2000個partition,每個partition擁有2個副本。當其中一個broker意外宕機,所有1000個partition同時變得不可用。假設每一個partition恢復時間是5ms,那么1000個partition的恢復時間將會花費5秒鍾,這可能對用戶來說就會有一個明顯的感知了。如果宕機的是controller節點,不可用時間將會更嚴重。

上述問題,通常情況下,都可以通過擴容集群來緩解,畢竟在不考慮成本的情況下,堆機器可以解決90%的問題。當然正常情況,還是得在合理的成本范圍內,進行合理的規划和調優,上述弊端一般都是能在可控范圍內的。

 

轉載:https://www.hyperxu.com/2020/01/01/kafka-4/


免責聲明!

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



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