<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【05期】消息隊列中,如何保證消息的順序性?

          共 1501字,需瀏覽 4分鐘

           ·

          2020-07-27 00:13

          e18859d4112184b32569154579bf66a8.webp程序員的成長之路互聯(lián)網(wǎng)/程序員/技術(shù)/資料共享?關(guān)注


          閱讀本文大概需要 2.5 分鐘。

          來自:java面試題精選

          問:如何保證消息的順序性?

          面試官心理分析

          其實這個也是用 MQ 的時候必問的話題,第一看看你了不了解順序這個事兒?第二看看你有沒有辦法保證消息是有順序的?這是生產(chǎn)系統(tǒng)中常見的問題。

          面試題剖析

          我舉個例子,我們以前做過一個 mysql?binlog?同步的系統(tǒng),壓力還是非常大的,日同步數(shù)據(jù)要達(dá)到上億,就是說數(shù)據(jù)從一個 mysql 庫原封不動地同步到另一個 mysql 庫里面去(mysql -> mysql)。常見的一點在于說比如大數(shù)據(jù) team,就需要同步一個 mysql 庫過來,對公司的業(yè)務(wù)系統(tǒng)的數(shù)據(jù)做各種復(fù)雜的操作。你在 mysql 里增刪改一條數(shù)據(jù),對應(yīng)出來了增刪改 3 條?binlog?日志,接著這三條?binlog?發(fā)送到 MQ 里面,再消費(fèi)出來依次執(zhí)行,起碼得保證人家是按照順序來的吧?不然本來是:增加、修改、刪除;你楞是換了順序給執(zhí)行成刪除、修改、增加,不全錯了么。本來這個數(shù)據(jù)同步過來,應(yīng)該最后這個數(shù)據(jù)被刪除了;結(jié)果你搞錯了這個順序,最后這個數(shù)據(jù)保留下來了,數(shù)據(jù)同步就出錯了。先看看順序會錯亂的倆場景:
          • RabbitMQ一個 queue,多個 consumer。比如,生產(chǎn)者向 RabbitMQ 里發(fā)送了三條數(shù)據(jù),順序依次是 data1/data2/data3,壓入的是 RabbitMQ 的一個內(nèi)存隊列。有三個消費(fèi)者分別從 MQ 中消費(fèi)這三條數(shù)據(jù)中的一條,結(jié)果消費(fèi)者2先執(zhí)行完操作,把 data2 存入數(shù)據(jù)庫,然后是 data1/data3。這不明顯亂了。


          a7fa6f5ec92a3f37f0fa7a5f465679ec.webp
          • Kafka比如說我們建了一個 topic,有三個 partition。生產(chǎn)者在寫的時候,其實可以指定一個 key,比如說我們指定了某個訂單 id 作為 key,那么這個訂單相關(guān)的數(shù)據(jù),一定會被分發(fā)到同一個 partition 中去,而且這個 partition 中的數(shù)據(jù)一定是有順序的。


            消費(fèi)者從 partition 中取出來數(shù)據(jù)的時候,也一定是有順序的。到這里,順序還是 ok 的,沒有錯亂。接著,我們在消費(fèi)者里可能會搞多個線程來并發(fā)處理消息因為如果消費(fèi)者是單線程消費(fèi)處理,而處理比較耗時的話,比如處理一條消息耗時幾十 ms,那么 1 秒鐘只能處理幾十條消息,這吞吐量太低了。而多個線程并發(fā)跑的話,順序可能就亂掉了。

          5e77e3d849cff039a6ec04b1fff4b21b.webp

          解決方案

          RabbitMQ

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

          Kafka

          • 一個 topic,一個 partition,一個 consumer,內(nèi)部單線程消費(fèi),單線程吞吐量太低,一般不會用這個。

          • 寫 N 個內(nèi)存 queue,具有相同 key 的數(shù)據(jù)都到同一個內(nèi)存 queue;然后對于 N 個線程,每個線程分別消費(fèi)一個內(nèi)存 queue 即可,這樣就能保證順序性。


          21f84b452f1f192ebf36c41cca6160ea.webp

          推薦閱讀:

          【04期】分庫分表之后,id 主鍵如何處理?

          【03期】如何決定使用 HashMap 還是 TreeMap?

          【02期】你能說說Spring框架中Bean的生命周期嗎?

          5T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機(jī),樹莓派,等等。在公眾號內(nèi)回復(fù)「2048」,即可免費(fèi)獲取!!

          微信掃描二維碼,關(guān)注我的公眾號

          寫留言

          朕已閱?0c5572ec607d49315605f0bf64490750.webp

          瀏覽 45
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人开心激情 | 看黑人免费操逼 | 免费播放一级A片 | 秋霞午夜成人无码精品 | 成人大香蕉网站精品免费 |