消息隊列如何保證順序性?


主要思路有兩種:1、單線程消費來保證消息的順序性;2、對消息進行編號,消費者處理時根據編號判斷順序。 

1、rabbitMq
問題分析:
imagepng
如圖,data1 和 data2 是有順序的,必須 data1 先執行,data2 后執行;這兩個數據被不同的消費者消費到了,可能 data2 先執行,data1 后執行,這樣原來的順序就錯亂了。

解決方案:
imagepng
如圖,在 MQ 里面創建多個 queue,同一規則的數據(對唯一標識進行 hash),有順序的放入 MQ 的 queue 里面,消費者只取一個 queue 里面獲取數據消費,這樣執行的順序是有序的。或者還是只有一個 queue 但是對應一個消費者,然后這個消費者內部用內存隊列做排隊,然后分發給底層不同的 worker 來處理。

2、kafka
問題分析:
imagepng
如圖,在 kafka 中,你對數據指定某個 key,那么這些數據會到同一個 partition 里面,在 partition 里面這些數據是有順序的。從這里看沒啥問題,插入到數據庫的數據都是有序的。

但是,我們在消費端可能會使用多線程來處理,因為單線程的處理速度慢,為了加快處理時間和吞吐量,會使用 thread 來處理。在消費端加入線程之后,就會出現順序不一致的情況。
imagepng
如圖,就是使用了多線程之后,數據順序不一致情況。

在使用了多線程之后,如何來解決數據順序問題?
imagepng
如圖,在消費端使用內存隊列,隊列里的數據使用 hash 進行分發,每個線程對應一個隊列,這樣可以保證數據的順序。

3、rocketMq
imagepng

如圖,生產者中把 orderId 進行取模,把相同模的數據放到 messagequeue 里面,消費者消費同一個 messagequeue,只要消費者這邊有序消費,那么可以保證數據被順序消費。

4、activeMq
imagepng
如圖,activeMq 里面有 messageGroups 屬性,可以指定 JMSXGroupID,消費者會消費指定的 JMSXGroupID。即保證了順序性,又解決負載均衡的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM