概述
Kafka是一個分佈式流平臺,它源自於日誌聚合案例,它不須要過高的併發性.在阿里巴巴的一些大型案例中,發現原來的模式已經不能知足的實際需求。所以,開發了一個名爲rocketmq的消息中間件,它能夠處理普遍的場景,從傳統的發佈/訂閱場景到要求高容量、不容許消息丟失的實時事務系統等。算法
Kafka的分區設計
- 生產者並行寫的性能受到分區數量的限制。
- 消費者並行消費的程度受消費的分區數限制。假設消費者分區的數量是20,那麼併發消費的最大數量是20.
- 每一個主題由固定數量的分區組成,分區數量決定單個代理在不會顯著影響性能的狀況下,可能擁有的主題最大數量。
如何選擇Kafka集羣中Topic分區數量數據庫
爲何Kafka不能支持更多的分區
- 每一個分區存儲整個消息數據。雖然每一個分區都是有序地寫入磁盤的,可是隨着併發寫入分區的增長,從操做系統的角度來看,寫入變得隨機。
- 因爲數據文件分散,很難使用Linux IO組提交機制。
RocketMQ 中是如何支持更多的分區的?
- 全部消息數據都存儲在提交日誌文件中,全部寫入都是徹底連續的,而讀取是隨機的。
- ConsumeQueue存儲用戶實際消費的位置信息,這些信息也按順序刷新到磁盤。
優點:編程
- 每一個消費隊列都變得輕量化,而且包含有限數量的元數據(數據量變少)。
- 對磁盤的訪問是徹底連續的,這樣能夠避免磁盤鎖爭奪,而且在建立大量隊列時不會致使高磁盤IO等待。
劣勢:緩存
- 消費消息將首先讀取消費隊列,而後提交日誌,在最壞的狀況下,過程會帶來必定的成本。
- 提交日誌和使用隊列須要邏輯一致,這會給編程模型帶來額外的複雜性。
設計的動機
- 隨機讀:儘量多地讀取以增長頁面緩存命中率,並減小讀取IO操做。因此在大內存狀況下是仍然是適合的。若是積壓了大量的消息,讀取的性能會嚴重降低嗎?答案是否認的。
緣由以下:併發
- 即便消息大小隻有1KB,系統也會提早讀取更的數據(緩存數據預取:參考PAGECACHE prefetch ),這意味着對於後續數據讀取,將執行對主內存的訪問,而不是慢速磁盤IO讀取。
- 從磁盤隨機訪問CommitLog,若是在SSD的狀況下將I/O調度器設置爲NOOP,那麼讀取qps的速度將大大加快,比其餘操做系統調度算法快得多。
-
因爲ConsumeQueue只存儲固定大小的元數據,主要用於記錄消費過程,所以支持隨機讀取。利用頁面緩存預取,即便是在大量消息積累的狀況下,訪問ConsumeQueue的速度與訪問主內存同樣快。所以,ConsumeQueue不會帶來明顯的讀取性能影響。分佈式
-
CommitLog幾乎存儲全部信息,包括消息數據。與關係數據庫的重作日誌相似,只要存在提交日誌,就能夠徹底恢復使用隊列、消息鍵索引和全部其餘所需數據。性能