mq消費(fèi)冪等總結(jié)

mq消費(fèi)冪等總結(jié)
針對(duì)mq新增場(chǎng)景:
1、單個(gè)新增:
1)首先查本地db是否已存在,存在則冪等
2)加redis樂(lè)觀鎖,加鎖失敗重試mq,
3)理論上上邊2步可以解決大部分?jǐn)?shù)據(jù)重復(fù)新增的問(wèn)題,但是針對(duì)并發(fā)情況下,樂(lè)觀鎖超時(shí)釋放的情況,數(shù)據(jù)庫(kù)需要加唯一索引(outId, outType)進(jìn)行兜底
2、批量新增:
1)單條加鎖處理(推薦):i.每次處理一個(gè),處理前檢查本地是否存在,存在則跳過(guò);
單條加redis樂(lè)觀鎖,加鎖失敗重試mq;執(zhí)行插入db
2)批量一起處理(不加鎖):i.批量校驗(yàn)是否存在,比較數(shù)量,相等則冪等,不相等則可能有缺失,計(jì)算出缺失的數(shù)據(jù),然后進(jìn)行插入db
ii.不存在:每次處理單條,加redis樂(lè)觀鎖,加鎖失敗重試mq,執(zhí)行插入db
針對(duì)mq更新場(chǎng)景:
1、單個(gè)更新:與新增類(lèi)似
2、批量更新:
1)每次處理單條主數(shù)據(jù),每條失敗都會(huì)重試全部
2)加redis樂(lè)觀鎖,加鎖失敗重試mq,
3)針對(duì)新增的數(shù)據(jù)進(jìn)行db冪等校驗(yàn),冪等則結(jié)束此條數(shù)據(jù)處理(for 循環(huán) continue)
4)針對(duì)更新的數(shù)據(jù),通過(guò)加數(shù)據(jù)庫(kù)version條件進(jìn)行db更新
5)針對(duì)刪除的數(shù)據(jù)進(jìn)行處理,如果沒(méi)有要?jiǎng)h除的,則結(jié)束此條數(shù)據(jù)處理(for 循環(huán) continue);
如果有要?jiǎng)h除的,則需要進(jìn)行db操作,一般的做法是變更db的狀態(tài)為刪除狀態(tài);
6)執(zhí)行db操作
針對(duì)mq刪除場(chǎng)景:
1、單個(gè)刪除:與新增類(lèi)似
2、批量刪除:
1)不加鎖的情況(推薦):判斷邏輯:批量查詢(xún)是否已刪除,刪除則冪等,未全部刪除,則進(jìn)行變更db;
i.每次更新時(shí)因?yàn)閹Я藇ersion條件,所以并發(fā)情況下可能更新失效,因?yàn)橐呀?jīng)db數(shù)據(jù)被變更,這種情況需要人工修數(shù)據(jù);
ii.失敗的情況下,全量回滾db操作;
2)加鎖的情況:1、鎖批量消息范圍太廣,導(dǎo)致鎖失效,不推薦
2、鎖單個(gè)消息(不推薦):
i.先校驗(yàn)db的數(shù)據(jù)狀態(tài)是否為已刪除,刪除則跳過(guò);
ii.并發(fā)情況下,因?yàn)槟硞€(gè)處理失敗,可能出現(xiàn)mq重試的情況
總結(jié)
不論哪種場(chǎng)景:
場(chǎng)景1:消息體是主表idList,實(shí)際插入db的是子表的記錄,
場(chǎng)景2:消息體的idList對(duì)應(yīng)實(shí)際插入db的idList;
批量操作新增、更新時(shí),推薦單條加鎖處理,每次鎖一條;
操作邏輯:1)判斷單條是否已操作過(guò)
2)加redis樂(lè)觀鎖,加鎖失敗重試mq,
3)對(duì)于新增:數(shù)據(jù)庫(kù)要加唯一索引來(lái)進(jìn)行兜底
對(duì)于更新:需要判斷3種操作情況(主子表結(jié)構(gòu)):判斷是新增、編輯、刪除
4)對(duì)于單條失敗處理:新增、更新:mq重試時(shí)會(huì)重試,重試之前需要判斷是否已變更(更新可不判斷)
5)對(duì)于單條已處理的冪等判斷:
對(duì)于更新、刪除數(shù)據(jù)單條冪等的判斷時(shí),可以不加redis樂(lè)觀鎖,但是要加數(shù)據(jù)庫(kù)version;
i.新增:1)首先查本地db是否已存在,存在則冪等
2)加redis樂(lè)觀鎖,加鎖失敗重試mq,
3)理論上上邊2步可以解決大部分?jǐn)?shù)據(jù)重復(fù)新增的問(wèn)題,但是針對(duì)并發(fā)情況下,樂(lè)觀鎖超時(shí)釋放的情況,數(shù)據(jù)庫(kù)需要加唯一索引(outId, outType)進(jìn)行兜底
ii.更新:不用判斷冪等,只需判斷版本號(hào)是否等于db的版本號(hào),在更新sql時(shí)加version做條件
iii.刪除:判斷是否已刪除,已刪除則冪等,未刪除則進(jìn)行db變更,在更新sql時(shí)加version做條件(數(shù)據(jù)庫(kù)仍存在,但狀態(tài)為已刪除)

數(shù)據(jù)庫(kù)設(shè)計(jì)時(shí)注意事項(xiàng):
1)需要對(duì)outId,outType加唯一索引
2)要有version字段,并維護(hù)好
3)要有刪除狀態(tài)字段,用于進(jìn)行刪除時(shí)變更

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

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

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