0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

消息隊(duì)列中如何保證消息的順序性?

馬哥Linux運(yùn)維 ? 來源:馬哥Linux運(yùn)維 ? 2023-09-08 09:40 ? 次閱讀

我舉個例子,我們以前做過一個 mysqlbinlog同步的系統(tǒng),壓力還是非常大的,日同步數(shù)據(jù)要達(dá)到上億,就是說數(shù)據(jù)從一個 mysql 庫原封不動地同步到另一個 mysql 庫里面去(mysql -> mysql)。常見的一點(diǎn)在于說比如大數(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)存隊(duì)列。有三個消費(fèi)者分別從 MQ 中消費(fèi)這三條數(shù)據(jù)中的一條,結(jié)果消費(fèi)者2先執(zhí)行完操作,把 data2 存入數(shù)據(jù)庫,然后是 data1/data3。這不明顯亂了。

2cc536fa-4d90-11ee-a25d-92fbcf53809c.png

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

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

2cd4e082-4d90-11ee-a25d-92fbcf53809c.png

解決方案

RabbitMQ

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

2ce667d0-4d90-11ee-a25d-92fbcf53809c.png

Kafka

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

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

2cf1d16a-4d90-11ee-a25d-92fbcf53809c.png

鏈接:https://www.jianshu.com/p/8a5630e2c317






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    789

    瀏覽量

    26283
  • MYSQL數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    0

    文章

    95

    瀏覽量

    9348
  • 消息隊(duì)列
    +關(guān)注

    關(guān)注

    0

    文章

    32

    瀏覽量

    2947
  • mysql觸發(fā)器
    +關(guān)注

    關(guān)注

    0

    文章

    6

    瀏覽量

    1099

原文標(biāo)題:面試官:消息隊(duì)列中如何保證消息的順序性?

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    FIFO隊(duì)列原理簡述

    FIFO是隊(duì)列機(jī)制中最簡單的,每個接口上只有一個FIFO隊(duì)列,表面上看FIFO隊(duì)列并沒有提供什么QoS保證,甚至很多人認(rèn)為FIFO嚴(yán)格意義上不算做一種
    發(fā)表于 07-10 09:22 ?1567次閱讀

    嵌入式開發(fā)消息隊(duì)列的實(shí)現(xiàn)

    在嵌入式開發(fā)中經(jīng)常會看到消息隊(duì)列的身影,隊(duì)列的應(yīng)用是很廣泛的,它可以應(yīng)用的場景有很多,比如緩存通信消息,暫存執(zhí)行內(nèi)容,數(shù)據(jù)順序轉(zhuǎn)發(fā)等的操作。
    發(fā)表于 08-22 11:19 ?975次閱讀
    嵌入式開發(fā)<b class='flag-5'>中</b>消息<b class='flag-5'>隊(duì)列</b>的實(shí)現(xiàn)

    局部變量與隊(duì)列的使用

    大家好,我有一個困擾很久的問題。我想將一個循環(huán)里的數(shù)據(jù)引用到另一個定時循環(huán)結(jié)構(gòu)里,如果用局部變量的話會出現(xiàn)數(shù)據(jù)丟失,但實(shí)時可以保證,如果用隊(duì)列的話保證了數(shù)據(jù)的完整
    發(fā)表于 05-22 14:31

    利用隊(duì)列控制多設(shè)備的控制結(jié)構(gòu)

    的積分,能幫忙解決的,全部奉上了...程序介紹:程序想實(shí)現(xiàn)功能:對一個系統(tǒng)的各個慢速響應(yīng)設(shè)備進(jìn)行控制,并且保證每個設(shè)備操作的順序和各個設(shè)備之間的響應(yīng)按照主程序分發(fā)任務(wù)的時間順序進(jìn)行由
    發(fā)表于 06-07 22:05

    數(shù)據(jù)結(jié)構(gòu)之隊(duì)列順序及其構(gòu)造

    數(shù)據(jù)結(jié)構(gòu)之隊(duì)列順序隊(duì)列構(gòu)造順序隊(duì)列順序隊(duì)列的初始化判
    發(fā)表于 12-17 06:11

    LabVIEW什么是隊(duì)列

    LabVIEW什么是隊(duì)列隊(duì)列維護(hù)數(shù)據(jù)項(xiàng)的先進(jìn)/先出(FIFO)順序。例如,在快餐店排隊(duì)等候的顧客在排隊(duì)。第一個被招待的客戶將是第一個到達(dá)的客戶。隊(duì)列在生產(chǎn)者/消費(fèi)者情況下很有用,其中一部分代碼正在
    發(fā)表于 04-09 21:35

    LabVIEW隊(duì)列使用詳解

    多。3.7清空隊(duì)列一次取出當(dāng)前隊(duì)列中所有的元素,返回一個元素?cái)?shù)組。3.8有損耗元素入隊(duì)列隊(duì)列
    發(fā)表于 09-05 00:07

    iFix組態(tài)軟件基于隊(duì)列的命令處理機(jī)制研究

    提出了一種在iFix 組態(tài)軟件創(chuàng)建消息隊(duì)列的方法,利用這種消息隊(duì)列實(shí)現(xiàn)了對控制命令的執(zhí)行情況的跟蹤與處理。這種基于隊(duì)列的命令處理機(jī)制確保了組態(tài)軟件的控制命令能夠
    發(fā)表于 12-23 14:06 ?22次下載

    FIFO隊(duì)列原理簡述 擁塞避免原理

    擁塞管理是指網(wǎng)絡(luò)在發(fā)生擁塞時,如何進(jìn)行管理和控制。FIFO隊(duì)列不對報(bào)文進(jìn)行分類,按報(bào)文到達(dá)接口的先后順序讓報(bào)文進(jìn)入隊(duì)列,采用盡力而為的轉(zhuǎn)發(fā)模式,PQ隊(duì)列是針對關(guān)鍵業(yè)務(wù)應(yīng)用設(shè)計(jì)的。
    發(fā)表于 02-23 08:35 ?1w次閱讀
    FIFO<b class='flag-5'>隊(duì)列</b>原理簡述 擁塞避免原理

    單片機(jī)實(shí)現(xiàn)FIFO循環(huán)隊(duì)列的代碼和資料免費(fèi)下載

    順序棧相類似,在隊(duì)列順序存儲結(jié)構(gòu),除了用一組地址連續(xù)的存儲單元依次存放從隊(duì)列頭到隊(duì)列尾的元
    發(fā)表于 09-19 17:19 ?2次下載
    單片機(jī)實(shí)現(xiàn)FIFO循環(huán)<b class='flag-5'>隊(duì)列</b>的代碼和資料免費(fèi)下載

    SystemVerilog隊(duì)列

    隊(duì)列是大小可變的有序集合,隊(duì)列中元素必須是同一個類型的。隊(duì)列支持對其所有元素的訪問以及在隊(duì)列的開始或結(jié)束處插入和刪除。
    的頭像 發(fā)表于 10-31 10:09 ?3719次閱讀

    什么是消息隊(duì)列?消息隊(duì)列中間件重要嗎?

    應(yīng)用解耦:消息隊(duì)列減少了服務(wù)之間的耦合,不同的服務(wù)可以通過消息隊(duì)列進(jìn)行通信,而不用關(guān)心彼此的實(shí)現(xiàn)細(xì)節(jié)。
    的頭像 發(fā)表于 11-07 14:55 ?1274次閱讀

    ZWave的消息隊(duì)列機(jī)制是什么

    這篇文章就來看看 ZWave 是通過什么機(jī)制為我們提供了一個便捷的消息隊(duì)列處理機(jī)制。
    的頭像 發(fā)表于 02-14 13:41 ?667次閱讀
    ZWave<b class='flag-5'>中</b>的消息<b class='flag-5'>隊(duì)列</b>機(jī)制是什么

    RTOS消息隊(duì)列的應(yīng)用

    基于RTOS的應(yīng)用,通常使用隊(duì)列機(jī)制實(shí)現(xiàn)任務(wù)間的數(shù)據(jù)交互,一個應(yīng)用程序可以有任意數(shù)量的消息隊(duì)列,每個消息隊(duì)列都有自己的用途。
    發(fā)表于 05-29 10:49 ?553次閱讀
    RTOS消息<b class='flag-5'>隊(duì)列</b>的應(yīng)用

    FreeRTOS消息隊(duì)列介紹

    隊(duì)列是為了任務(wù)與任務(wù)、任務(wù)與中斷之間的通信而準(zhǔn)備的,可以在任務(wù)與任務(wù)、任務(wù)與中斷之間傳遞消息,隊(duì)列可以存儲有限的、大小固定的數(shù)據(jù)項(xiàng)目。任務(wù)與任務(wù)、任務(wù)與中斷之間要交流的數(shù)據(jù)保存在隊(duì)列
    的頭像 發(fā)表于 07-06 16:58 ?700次閱讀
    FreeRTOS消息<b class='flag-5'>隊(duì)列</b>介紹