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

Kafka:比如說我們建了一個(gè) topic,有三個(gè) partition。生產(chǎn)者在寫的時(shí)候,其實(shí)可以指定一個(gè) key,比如說我們指定了某個(gè)訂單 id 作為 key,那么這個(gè)訂單相關(guān)的數(shù)據(jù),一定會(huì)被分發(fā)到同一個(gè) partition 中去,而且這個(gè) partition 中的數(shù)據(jù)一定是有順序的。
消費(fèi)者從 partition 中取出來數(shù)據(jù)的時(shí)候,也一定是有順序的。到這里,順序還是 ok 的,沒有錯(cuò)亂。接著,我們?cè)谙M(fèi)者里可能會(huì)搞多個(gè)線程來并發(fā)處理消息。因?yàn)槿绻M(fèi)者是單線程消費(fèi)處理,而處理比較耗時(shí)的話,比如處理一條消息耗時(shí)幾十 ms,那么 1 秒鐘只能處理幾十條消息,這吞吐量太低了。而多個(gè)線程并發(fā)跑的話,順序可能就亂掉了。

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

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

鏈接:https://www.jianshu.com/p/8a5630e2c317
審核編輯:劉清
-
MySQL
+關(guān)注
關(guān)注
1文章
897瀏覽量
29191 -
MYSQL數(shù)據(jù)庫
+關(guān)注
關(guān)注
0文章
96瀏覽量
10191 -
消息隊(duì)列
+關(guān)注
關(guān)注
0文章
34瀏覽量
3234 -
mysql觸發(fā)器
+關(guān)注
關(guān)注
0文章
6瀏覽量
1189
原文標(biāo)題:面試官:消息隊(duì)列中如何保證消息的順序性?
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
FIFO隊(duì)列原理簡述
嵌入式開發(fā)中消息隊(duì)列的實(shí)現(xiàn)
利用隊(duì)列控制多設(shè)備的控制結(jié)構(gòu)
數(shù)據(jù)結(jié)構(gòu)之隊(duì)列順序及其構(gòu)造
LabVIEW什么是隊(duì)列
LabVIEW中的隊(duì)列使用詳解
iFix組態(tài)軟件中基于隊(duì)列的命令處理機(jī)制研究
FIFO隊(duì)列原理簡述 擁塞避免原理
單片機(jī)實(shí)現(xiàn)FIFO循環(huán)隊(duì)列的代碼和資料免費(fèi)下載
SystemVerilog中的隊(duì)列
什么是消息隊(duì)列?消息隊(duì)列中間件重要嗎?
RTOS消息隊(duì)列的應(yīng)用
FreeRTOS消息隊(duì)列介紹

消息隊(duì)列中如何保證消息的順序性?
評(píng)論