kafka?rabbitMQ及rocketMQ隊列的消息可靠性保證分析
1.消息丟失
1.生產者發(fā)送失敗
所有消息隊列都可能發(fā)生的問題
- 生產者發(fā)送消息后,隊列未成功接收(網絡原因或其他)而生產者不知情,消息丟失
- 生產者發(fā)送消息后,隊列接收成功->生產者確認,但消息并未持久化,隊列崩潰,消息丟失
針對這類問題,三種消息隊列都提供了生產者消息發(fā)送確認的模式,例如將kafka的acks參數(shù)設置為大于0,將rabbitMQ的信道設置為confirm模式。而在rocketMQ中會返回消息發(fā)送狀態(tài)碼。其中rabbitMQ和rocketMQ還提供了生產者事務操作。
只有某些消息隊列才會發(fā)生的問題
- kafka和rabbitMQ在集群狀態(tài)下當前首領不可用時會進行首領選舉。在kafka中,如果把acks設置為1(只要首領節(jié)點收到生產者發(fā)送的消息即確認發(fā)送成功)時,若當前首領收到的消息但還未同步至從任一節(jié)點就崩潰了,kafka會在還來不及判定的非同步從節(jié)點中選舉出首領,這時消息丟失,解決方式是將acks設置未all,即全部從節(jié)點同步成功再確認。而在rabbitMQ中,新加入的鏡像節(jié)點不會同步在此之前的消息,當老的消息還未完全消費完,老節(jié)點全部崩潰時,新節(jié)點被選舉為首領時,會丟失所有未消費的舊消息(目前好像沒有什么好的解決方式)。
- kafka中,即使及時的將所有未同步消息的節(jié)點成功判定未非同步節(jié)點,也要在消息丟失和系統(tǒng)不可用之間做出權衡,如果不希望消息丟失,則在首領節(jié)點恢復前整個系統(tǒng)不可用,通過參數(shù)unclean.leader.election.enable可以設置非同步副本是否能成為首領節(jié)點。
- rocketMQ集群環(huán)境下,broker主從使用異步復制模式時,若master節(jié)點崩潰且數(shù)據(jù)無法恢復,會丟失還未同步至從節(jié)點的部分消息,解決方式是使用同步雙寫的方式同步消息,但會降低吞吐率。
2.消費者消費失敗
與生產者類似,若消費者在消費消息失敗時未告知消息隊列,此消息丟失。kafka,rabbitMQ,rocketMQ都提供了相似的消費成功確認機制來解決這個問題,rabbitMQ通過auto_ack參數(shù)設置自動確認或手動確認。
而rocketMQ和kafka通過消息偏移量來控制信息消費,rocketMQ在pull模式下需要自己維護偏移量。
3.隊列因為自身體原因丟失數(shù)據(jù)
這個很好理解,例如rabbitMQ默認將消息保存再內存中,如果隊列崩潰,消息自然丟失
2.消息順序
1.kafka
kafka保證同一分區(qū)內消息的順序,也就是說,如果要讓某一topic內消息全部有序,只能為該topic設置一個分區(qū),這會降低該主題的吞吐量。通常使用消息的key值將消息散布到不同分區(qū)上,以此保證消息的局部有序性,但這種局部有序性的保證僅僅在消息寫入分區(qū)時是有序的才能保證,例如生產者按順序消息寫入消息A,消息B,消息A寫入失敗,消息B寫入成功,生產者重發(fā)消息A且成功,這時候兩個消息的順序就顛倒了,解決方式是設定max.in.flight.requests.per.connection為1,指定生產者在收到消息成功發(fā)送的確認之前不允許發(fā)送其他信息,但這種方式也會嚴重降低吞吐量。
另一個問題是kafka默認的分區(qū)器使用散列算法將消息的key值映射到對映的分區(qū)上,如果增加了分區(qū),key值映射的分區(qū)可能會與之前的不一致。在kafka中,一個分區(qū)只能被一個消費者消費,保證了消息消費的局部有序性。
2.rocketMQ
rocketMQ的隊列(Message Queue)與kafka的分區(qū)在概念上相似,所以rocketMQ在消息有序性的保證上自然也是基于隊列(Message Queue)的,同kafka一樣,如果要讓某一主題內的消息有序,必須將此主題內的獨寫隊列數(shù)量設為1,但和kafka一樣,這種操作會大量降低該主題的吞吐量。
rocketMQ中在發(fā)送消息時傳入自定義的MessageQueueSelector保證消息生產的局部有序性,在消費消息時push模式下通過MessageListenerOrderly保證順序消費。
3.rabbitMQ
對于rabbitMQ,我沒有找到相關的資料,個人猜測,rabbitMQ同一隊列內消息的有序性應該是有保障的,但大多數(shù)人會在生產者和消費者中增加消息有序性判斷
3.消息重復
幾乎所有的消息隊列中都未能提供不重復消息的保證,而且消息重復與消息丟失幾乎是二選一的問題,大多數(shù)情況下我們選擇保證消息不丟失而容忍一部分消息重復,最廣泛的解決消息重復的方式是在消費者端對消息進行驗證或者保證消費的冪等性
以上就是kafka rabbitMQ及rocketMQ隊列的消息可靠性保證分析的詳細內容,更多關于kafka rabbitMQ rocketMQ消息隊列的資料請關注腳本之家其它相關文章!
相關文章
Websocket直播間聊天室教程 GoEasy快速實現(xiàn)聊天室
這篇文章主要介紹了Websocket直播間聊天室教程 GoEasy快速實現(xiàn)聊天室,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05IDEA中使用Git拉取代碼時報 Git pull failed原因及解決方法
這篇文章主要介紹了IDEA中使用Git拉取代碼時報 Git pull failed原因及解決方法,本文給大家介紹的非常詳細對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08Jenkins使用publish?html?report插件展示HTML報告的方法
這篇文章主要介紹了Jenkins使用publish?html?report插件展示HTML報告的方法,展示普通的html如何展示在jenkins上,本文通過圖文并茂的形式給大家介紹的非常詳細,需要的朋友可以參考下2022-03-03IntelliJ IDEA2020新增禪模式和LightEdit模式
這篇文章主要介紹了IntelliJ IDEA2020新增禪模式和LightEdit模式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03