我們知道當消息生產(chǎn)者生產(chǎn)的速度快于消費者的消費速度時,會產(chǎn)生大量的消息積壓,大多數(shù)人的想法是增加消費者的數(shù)量來提升消費速度,這個想法在RocketMQ中是可行的,但是在Kafka中不一定可行。為了更方便地分析問題,我們先忽略消費者組的設計,在增加消費者之前,架構設計,請看下圖
一個topic下面建立了兩個分區(qū),partition-0和partition-1,分別被consumer-0和consumer-1消費,此時消息積壓了很多,我們試圖增加一個consumer-2,來增加partition的消費速度
你會發(fā)現(xiàn)消費速度沒有變化,這是因為Kafka在一開始設計Parition的時候,就已經(jīng)設計成了一個Parition在同一個時刻只能被一個Consumer消費,當消費者數(shù)量大于分區(qū)數(shù)量時,新加入的消費者是消費不到消息的,除非之前的分區(qū)數(shù)量是小于消費者數(shù)量,就像下圖所示
Kafka之所以這樣設計的原因有以下幾點:
- 保證分區(qū)局部有序性。一個分區(qū)同一時刻只能讓一個消費者消費,這樣有助于保證分區(qū)內的消息是有序的,能夠實現(xiàn)在局部消息的順序性,如果同時讓多個消費者消費,必然會破壞分區(qū)的順序性
- 消費者組更好地協(xié)作和高吞吐。Kafka的集群消費模式中,一個消息只能被一個消費者組中的一個消費者消費,如果你要讓一個Consumer消費Partion-0和Partion-1,那么其他的Consumer也要消費Partition-0和Partion-1,如果恰好出現(xiàn)Partiion-0的一條消息同時被兩個Consumer拉取到,將會出現(xiàn)消息競爭,需要加鎖來控制,這樣勢必會降低性能,這與Kafka高吞吐的理念相悖
Kafka如果要對新加入的消費者實例進行rebalance,那么Kafka整體將會不可用,直到rebalance結束,而RocketMQ則會通過Consumer的負載均衡機制,讓每個MessageQueue都會分配到一個Consumer,而不會發(fā)生不可用
所以在水平擴容消費者上面,相對RocketMQ來說不是那么地直接,在Kafka中需要做進一步考慮,多說一句,在RocketMQ中由于業(yè)務場景不同,相比Kafka處理的業(yè)務場景要復雜地多,所以RocketMQ需要支持消費者的水平擴容,這樣就會出現(xiàn)消息競爭,但是為了水平擴容,RocketMQ需要這樣做。文章來源:http://www.zghlxwxcb.cn/news/detail-816131.html
對比RocketMQ
RocketMQ在大多數(shù)情況下只會被同一個消費者組中的一個消費者實例消費,以保證消息的有序性。
但是在有些情況下,RocketMQ也支持消息負載均衡,即允許同一個MessageQueue被同一個消費者組中的多個消費者實例共同消費,文章來源地址http://www.zghlxwxcb.cn/news/detail-816131.html
- 消息負載均衡: 如果消費者組中存在一個實例處理速度較快,RocketMQ可能會將同一個MessageQueue分配給這個組中的其他相對較慢的實例,以實現(xiàn)負載均衡
- 動態(tài)擴容:也就是我們討論的動態(tài)增加消費者實例時,新加入的實例可能會被分配到已有實例所消費的MessageQueue上,以實現(xiàn)動態(tài)擴容
到了這里,關于Kafka為什么在消息積壓時不能直接通過消費者水平擴容來提升消費速度?的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!