消息中間件面試題:如何保證消息的順序性

面試題

如何保證消息的順序性?

消息中間件各種面試題:
消息中間件面試題:消息丟失怎么辦?
消息中間件面試題:消息隊(duì)列的優(yōu)缺點(diǎn),區(qū)別
消息中間件面試題:消息中間件的高可用
消息中間件面試題:如何保證消息的順序性
消息中間件面試題:如何保證消息不被重復(fù)消費(fèi)
消息中間件面試題:如何解決消息隊(duì)列的延時(shí)以及過期失效問題?消息隊(duì)列滿了以后該怎么處理?有幾百萬消息持續(xù)積壓幾小時(shí)呢?
消息中間件面試題:如果讓你寫一個(gè)消息隊(duì)列,該如何進(jìn)行架構(gòu)設(shè)計(jì)?

面試題剖析

我舉個(gè)例子,我們以前做過一個(gè) mysql binlog 同步的系統(tǒng),壓力還是非常大的,日同步數(shù)據(jù)要達(dá)到上億,就是說數(shù)據(jù)從一個(gè) mysql 庫原封不動地同步到另一個(gè) mysql 庫里面去(mysql -> mysql)。常見的一點(diǎn)在于說比如大數(shù)據(jù) team,就需要同步一個(gè) mysql 庫過來,對公司的業(yè)務(wù)系統(tǒng)的數(shù)據(jù)做各種復(fù)雜的操作。

你在 mysql 里增刪改一條數(shù)據(jù),對應(yīng)出來了增刪改 3 條 binlog 日志,接著這三條 binlog 發(fā)送到 MQ 里面,再消費(fèi)出來依次執(zhí)行,起碼得保證人家是按照順序來的吧?不然本來是:增加、修改、刪除;你楞是換了順序給執(zhí)行成刪除、修改、增加,不全錯了么。

本來這個(gè)數(shù)據(jù)同步過來,應(yīng)該最后這個(gè)數(shù)據(jù)被刪除了;結(jié)果你搞錯了這個(gè)順序,最后這個(gè)數(shù)據(jù)保留下來了,數(shù)據(jù)同步就出錯了。

先看看順序會錯亂的倆場景:

  • RabbitMQ:一個(gè) queue,多個(gè) consumer。比如,生產(chǎn)者向 RabbitMQ 里發(fā)送了三條數(shù)據(jù),順序依次是 data1/data2/data3,壓入的是 RabbitMQ 的一個(gè)內(nèi)存隊(duì)列。有三個(gè)消費(fèi)者分別從 MQ 中消費(fèi)這三條數(shù)據(jù)中的一條,結(jié)果消費(fèi)者2先執(zhí)行完操作,把 data2 存入數(shù)據(jù)庫,然后是 data1/data3。這不明顯亂了。
rabbitmq-order-01
  • Kafka:比如說我們建了一個(gè) topic,有三個(gè) partition。生產(chǎn)者在寫的時(shí)候,其實(shí)可以指定一個(gè) key,比如說我們指定了某個(gè)訂單 id 作為 key,那么這個(gè)訂單相關(guān)的數(shù)據(jù),一定會被分發(fā)到同一個(gè) partition 中去,而且這個(gè) partition 中的數(shù)據(jù)一定是有順序的。
    消費(fèi)者從 partition 中取出來數(shù)據(jù)的時(shí)候,也一定是有順序的。到這里,順序還是 ok 的,沒有錯亂。接著,我們在消費(fèi)者里可能會搞多個(gè)線程來并發(fā)處理消息。因?yàn)槿绻M(fèi)者是單線程消費(fèi)處理,而處理比較耗時(shí)的話,比如處理一條消息耗時(shí)幾十 ms,那么 1 秒鐘只能處理幾十條消息,這吞吐量太低了。而多個(gè)線程并發(fā)跑的話,順序可能就亂掉了。
kafka-order-01

解決方案

RabbitMQ

拆分多個(gè) queue,每個(gè) queue 一個(gè) consumer,就是多一些 queue 而已,確實(shí)是麻煩點(diǎn);或者就一個(gè) queue 但是對應(yīng)一個(gè) consumer,然后這個(gè) consumer 內(nèi)部用內(nèi)存隊(duì)列做排隊(duì),然后分發(fā)給底層不同的 worker 來處理。


rabbitmq-order-02

Kafka

  • 一個(gè) topic,一個(gè) partition,一個(gè) consumer,內(nèi)部單線程消費(fèi),單線程吞吐量太低,一般不會用這個(gè)。
  • 寫 N 個(gè)內(nèi)存 queue,具有相同 key 的數(shù)據(jù)都到同一個(gè)內(nèi)存 queue;然后對于 N 個(gè)線程,每個(gè)線程分別消費(fèi)一個(gè)內(nèi)存 queue 即可,這樣就能保證順序性。
kafka-order-02

關(guān)注我,這里只有干貨!

本文原創(chuàng)地址:https://jsbintask.cn/2019/01/28/interview/interview-middleware-order/,轉(zhuǎn)載請注明出處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容