broker的數量最好大於等於partition數量
一個partition最好對應一個硬盤,這樣能最大限度發揮順序寫的優勢。
broker如果免得是多個partition,需要隨機分發,順序IO會退化成隨機IO。
實驗條件:3個 Broker,1個 Topic,無Replication,異步模式,3個 Producer,消息 Payload 為100字節:
當 Partition 數量小於 Broker個數時,Partition 數量越大,吞吐率越高,且呈線性提升。
Kafka 會將所有 Partition 均勻分布到所有Broker 上,所以當只有2個 Partition 時,會有2個 Broker 為該 Topic 服務。3個 Partition 時同理會有3個 Broker 為該 Topic 服務。
當 Partition 數量多於 Broker 個數時,總吞吐量並未有所提升,甚至還有所下降。
可能的原因是,當 Partition 數量為4和5時,不同 Broker 上的 Partition 數量不同,而 Producer 會將數據均勻發送到各 Partition 上,這就造成各Broker 的負載不同,不能最大化集群吞吐量。
• 當broker數量大於partition數量,則有些broker空閑,此時增加partition會帶來性能提升。而且是線性增長。
• 當兩者相等,則所有broker都啟用,吞吐達到瓶頸。
• 繼續增加,則broker會不均衡,有點會分到更多的partition。
順序IO退化成隨機IO。
consumer數量最好和partition數量一致
假設有一個 T1 主題,該主題有 4 個分區;同時我們有一個消費組 G1,這個消費組只有一個消費者 C1。
那么消費者 C1 將會收到這 4 個分區的消息。
如果我們增加新的消費者 C2 到消費組 G1,那么每個消費者將會分別收到兩個分區的消息。
相當於 T1 Topic 內的 Partition 均分給了 G1 消費的所有消費者,在這里 C1 消費 P0 和 P2,C2 消費 P1 和 P3。
如果增加到 4 個消費者,那么每個消費者將會分別收到一個分區的消息。 這時候每個消費者都處理其中一個分區,滿負載運行。
但如果我們繼續增加消費者到這個消費組,剩余的消費者將會空閑,不會收到任何消息。
總而言之,我們可以通過增加消費組的消費者來進行水平擴展提升消費能力。 這也是為什么建議創建主題時使用比較多的分區數,這樣可以在消費負載高的情況下增加消費者來提升性能。
另外,消費者的數量不應該比分區數多,因為多出來的消費者是空閑的,沒有任何幫助。 如果我們的 C1 處理消息仍然還有瓶頸,我們如何優化和處理?
把 C1 內部的消息進行二次 sharding,開啟多個 goroutine worker 進行消費,為了保障 offset 提交的正確性,需要使用 watermark 機制,保障最小的 offset 保存,才能往 Broker 提交。
● 保證順序性,避免大的offest先提交,小的offest掛了,重啟后會消息丟失。
● 解決:開一個協程專門提交offest,保證只提交最小的,重復消費代替消息丟失。
Kafka 一個很重要的特性就是,只需寫入一次消息,可以支持任意多的應用讀取這個消息。 換句話說,每個應用都可以讀到全量的消息。為了使得每個應用都能讀到全量消息,應用需要有不同的消費組。
對於上面的例子,假如我們新增了一個新的消費組 G2,而這個消費組有兩個消費者如圖。 在這個場景中,消費組 G1 和消費組 G2 都能收到 T1 主題的全量消息,在邏輯意義上來說它們屬於不同的應用。
最后,總結起來就是:如果應用需要讀取全量消息,那么請為該應用設置一個消費組;如果該應用消費能力不足,那么可以考慮在這個消費組里增加消費者。