您好,登錄后才能下訂單哦!
如果消息隊列有序是否要確保Producer和Consumer都有序,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
要想實現消息有序,需要從 Producer 和 Consumer 兩方面來考慮。
首先,Producer 生產消息的時候就必須要有序。
然后,Consumer 消費的時候,也要按順序來,不能亂。
像 RabbitMQ 這類普通的消息系統,隊列結構簡單,Producer 向隊列中發送消息就完了,進入隊列的消息肯定是有序的。
Kafka 比較特殊,因為它的一個 Topic(就是隊列的概念)實際上分為了多個 Partition。
Producer 發送消息的時候,是分散在不同 Partition 的。
Producer 按順序發消息,但進入 Kafka Topic 之后,這些消息就不一定進到哪個 Partition 了,所以順序肯定是亂的。
如果想 Topic 內的消息全局有序,就只能設置一個 Partition 了,這就變成了 RabbitMQ 那種結構。
但這種結構不符合 Kafka 的設計理念,Topic 只有一個 Partition 就失去了擴展性。
kafka 還支持一種局部有序的方式,就是把某一類的消息都放入同一個 Partition,就保證了這組消息的順序。
在發消息的時候指定 Partition Key,Kafka 對其進行 Hash 計算,根據計算結果決定放入哪個 Partition。
所以,Partition Key 一樣的消息肯定是在一起的。
例如使用用戶 ID 做 key,這樣同一個用戶的消息肯定是在一起的,就保證了這一組的消息的有序。
MQ 內消息有序,那么 Consumer 自然也是按順序接收的。
但是,如果使用了多個 Consumer,就可能出現亂序。
例如 RabbitMQ 的一個 Queue 有 3個 Consumer,雖然會按順序接收到消息,但是它們各自的處理速度是不同的,所以,出來的結果很可能是亂序的。
如果想嚴格按順序來,就只能使用一個 Consumer。
如果可以使用局部有序,那么就把之前的一個隊列拆為多個隊列,就像 Kafka 的 Partition Key 一樣,把同組數據放入同一個隊列。
Kafka 中一個 Partition 只能對應一個 Consumer,但如果 Consumer 使用了多線程,就和多個 Consumer 一個效果了,還是會造成亂序。
這樣的話就需要進一步細化消息的分組。
為每個線程創建一個內存隊列,Consumer 收到消息后,把同組的消息都放在同一個內存隊列,由同一個線程處理即可。
小結一下,消息的有序需要 Producer 和 Consumer 都有序。
RabbitMQ 的隊列結構簡單,Producer 發送的消息是有序的。但 Kafka 特殊,一個 Topic 有多個 Partition,如果要求全局有序,就只能使用一個 Partition。
如果可以接受局部有序,就可以為消息設置 Partition Key,其 Hash 計算結果相同的消息都會在同一個 Partition。
Consumer 消費時需要注意多 Consumer 的情況,例如多個消費線程。
可以在 Consumer 收到消息后再細化分組,同組的消息交給同一個消費線程處理。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。