卡夫卡的分區設計
- 生產者寫作的並行性受分區數量的限制。
- 消費者消費並行度也受到消費分區數量的限制。假設分區數為20,則最大並發消費消費者數為20。
- 每個主題由固定數量的分區組成。分區編號確定單個代理可能具有的最大主題數,而不會顯着影響性能。
更多細節請參考這里。
為什么Kafka不能支持更多分區
- 每個分區都存儲整個消息數據。盡管每個分區都按順序寫入磁盤,但隨着並發寫入分區數量的增加,從操作系統的角度來看,寫入變得隨機。
- 由於分散的數據文件,很難使用Linux IO組提交機制。
如何在RocketMQ中支持更多分區?
- 所有消息數據都存儲在提交日志文件中。所有寫入都是完全順序的,而讀取是隨機的。
- ConsumeQueue存儲實際的用戶消費位置信息,這些信息也以順序方式刷新到磁盤。
優點:
- 每個使用隊列都是輕量級的,並且包含有限數量的元數據。
- 對磁盤的訪問是完全順序的,這可以避免磁盤鎖爭用,並且在創建大量隊列時不會導致高磁盤IO等待。
缺點:
- 消息消耗將首先讀取消耗隊列,然后提交日志。在最壞的情況下,該過程會帶來一定的成本。
- 提交日志和使用隊列需要在邏輯上保持一致,這為編程模型帶來了額外的復雜性。
設計動機:
- 隨機閱讀。盡可能多地讀取以提高頁面緩存命中率,並減少讀取IO操作。如此大的內存仍然是可取的。如果累積大量消息,讀取性能是否會嚴重降低?答案是否定的,原因如下:
- 即使消息的大小僅為1KB,系統也會提前讀取更多數據,請參閱PAGECACHE預取以供參考。這意味着對於續集數據讀取,它將訪問將執行的主存儲器而不是慢速磁盤IO讀取。
- 從磁盤隨機訪問CommitLog。如果在SSD的情況下將I / O調度程序設置為NOOP,則讀取qps將大大加速,因此比其他電梯調度程序算法快得多。
- 鑒於ConsumeQueue僅存儲固定大小的元數據,主要用於記錄消費進度,因此可以很好地支持隨機讀取。利用頁面緩存預取,訪問ConsumeQueue與訪問主內存一樣快,即使是在大量消息累積的情況下也是如此。因此,ConsumeQueue不會對讀取性能帶來明顯的損失。
- CommitLog幾乎存儲所有信息,包括消息數據。與關系數據庫的重做日志類似,只要提交日志存在,就可以完全恢復消耗隊列,消息密鑰索引和所有其他所需數據。