摘要:啟發從事務消息談分布式事務事務消息本質上解決的問題是業務系統與消息系統之間的事務問題跨系統分布式事務,其基本原理即兩階段提交以及最終一致性保障。準備工作創建兩個隊列事務消息隊列消息的有效期小于消息延遲時間。消息延遲時間為事務操作超時時間。
啟發:從MNS事務消息談分布式事務
事務消息本質上解決的問題是業務系統與消息系統之間的事務問題(跨系統分布式事務),其基本原理即兩階段提交以及最終一致性保障。最近看了下阿里云mns事務消息的實現原理,介紹的蠻簡潔透徹的,對了解分布式事務實現原理挺有幫助,在閱讀本文前推薦大家先仔細閱讀下阿里云"mns事務消息"一文。
事務消息 背景描述有時候我們需要實現本地操作和消息發送的事務一致性功能。即:消息發送成功,則本地操作成功;反之,如果消息發送失敗,本地操作失敗(成功也需要rollback)。保證不出現操作成功但消息發送失敗;或者操作失敗但消息發送成功的情況;
解決方案
另外,消費端,我們也希望消息一定被成功處理一次,不會因為消息端程序崩潰而導致消息沒有成功處理,進而需要人工重置消費進度。利用消息服務MNS的延遲消息功能來實現。
準備工作 創建兩個隊列:
1.事務消息隊列
消息的有效期小于消息延遲時間。即如果生產者不主動修改(提交)消息可見時間,消息對消費者不可見;
2.操作日志隊列
記錄事務消息的操作記錄信息。消息延遲時間為事務操作超時時間。日志隊列中的消息確認(刪除)后將對消費者不可見。具體步驟1.發送一條事務準備消息到事務消息隊列;
2.寫操作日志信息到操作日志隊列,日志中包含步驟1消息的消息句柄;
3.執行本地事務操作;
4.如果步驟3成功,提交消息(消息對消費者可見);反之,回滾消息;
5.確認步驟2中的操作日志(刪除該日志消息);
6.步驟4后,消費者可以接收到事務消息;
7.消費者處理消息;
8.消費者確認刪除消息;
如下圖:
異常分析: 生產者異常(例如:進程重啟):A.讀取操作日志隊列超時未確認日志
消費者異常(例如:進程重啟):
B.檢查事務結果
C.如果檢查得到事務已經成功,則提交消息(重復提交無副作用,同一句柄的消息只能成功提交一次)
D.確認操作日志消息服務提供至少保證消費一次的特性,只要步驟8不成功,消息在一段時間后可以繼續可見,被當前消費者或者其他消費者處理。
消息服務不可達(例如:斷網)消息發送和接收處理狀態以及操作日志都在消息服務端,消息服務本身具備高可靠和高可用的特點,所以只要網絡恢復,事務可以繼續,能保證只要生產者:操作成功,則消費者一定能夠拿到消息并處理成功;或操作失敗, 則消費者收不到消息的最終一致性。
原文地址
在mns消息模型中兩階段提交的體現是:1.在執行事務前先preSendMessage:其背后的原理是創建一個delay message,但是這個delay message的delaytime > lifetime, 基于這個前提在得到確切的commit/rollback操作前,這個消息對于接受者是永遠不可見的;
2.本地事務結束后commit/rollback message:如果本地事務提交成功,需要將之前提交的delay message設置為消費者可見(底層實現應該與將delay變為0類似);對應的如果本地事務提交失敗,需要將之前的delay message刪除;
這個過程需要注意到,我們務必保證在preSendMessage沒得到最終確認之前不被消費者獲取到,因此需要將發送的lifetime小于delaytime。
看到這里也許你有疑問,為什么要將過程切分成兩階段提交?我們先假設如果采用一次提交的策略,很顯然這次提交的切入點只能存在于①本地事務開始之前②本地事務中③本地事務結束之后,那么先看這三個切入點各自存在什么問題。
①本地事務開始之前提交消息:在本地事務未完成之前,消息的消費者讀取到了message,如果消費者后續的服務調用中存在對該次本地事務提交有依賴,那必然導致數據不一致問題;如果本地事務的執行結果是失敗的,卻通知了消費者,很顯然會導致不可預期的數據錯誤。
②本地事務中:在本地事務中提交消息同樣會存在①中的問題,即便sendmessage是在本地事務的最后執行,因為事務的提交和消息被接受到的時序是無法保證的;
③本地事務結束之后:不同于①②兩個提交點,本地事務完成之后我們能夠明確的知道本地事務的執行結果,因此能夠確保事務提交(回滾)與消息被接受是有序的;然而如果消息沒有被成功發送消費者接受不到消息,而本地事務卻得到了正確執行,這就導致了數據不一致問題,并且如果沒有操作日志,這個問題將變得難以追溯;
”單次提交“遇到的主要問題是:無法保障本地事務與消息被接受到的時序問題(或者說兩個分布式事務的時序)以及數據的一致性問題。再回到”兩階段提交“,兩階段提交能解決這兩個問題嗎?兩階段提交的確認操作是在本地事務完成之后(這個類似于③),因此其能夠解決時序問題,但是如果這個確認操作執行的過程中發生了宕機等情況導致確認操作失敗,依然會導致數據不一致問題。
在mns事務消息中最終一致性的實現:mns通過延遲消息機制實現了兩階段提交,其如何保證數據一致性問題呢?一般我們的策略都是通過操作流水來進行補償以達到數據的最終一致性,同樣的mns也是基于這個原理實現。
在preSendMessage之后,mns會在日志隊列中記錄一條opLog(opLog通過記錄preSendMessage的receipthandle來進行關聯),并且將這個opLog的delayTime設置為事務的超時時間;
當本地事務執行結束,并且preSendMessage被commit/rollback之后,再將這條opLog刪除;
同時存在一個任務監聽日志隊列,當接收到opLog的消息,檢查對應的preSendMessage相關聯的本地事務是否執行成功。如果本地事務執行成功,則通過opLog中保存的receipthandle補償一次對preSendMessage的commit操作,如果checker發現本地事務執行失敗,那對應的補償一次rollback操作;
通過建立對opLog的監聽,我們能夠確保事務的最終一致性嗎?回答這個問題前,我們先看這個問題的本質:最終、一致性。
最終一致性問題的產生是由于發生了一些不可預期的問題,導致一個事務被提交(回滾),但消息沒被commit(rollback)。我們通過opLog來追溯那些沒有得到最終確認的消息并進行補償(最終),并且通過檢查本地事務的狀態來確認這次補償是commit或者是rollback(一致性)。正是基于這個補償的策略,mns事務消息解決了"兩階段提交"所遺留的一致性問題,但這個過程中我們需要注意幾個細節:
補償策略執行的時候需要明確知道本地事務的執行結果,因此我們的本地事務中需要記錄preSendMessage所關聯的本地事務操作結果。我們的做法是本地事務中同時記錄下preSendMessage的receipthandle, 當補償任務執行的時候,會通過opLog關聯的receipthandle來檢查,如果沒有找到相關記錄,那認為之前的本地事務被rollback了,否則commit;
MNS如何建立了preSendMessage<=>Local Transaction<=>opLog之間的關聯關系?最簡單的實現肯定是通過preSendMessage的MessageId來實現,不過mns通過preSendMessage的receipthandle來建立了這個關聯(ReceiptHandle含義)同時避免了額外的存儲;
mns的補償機制建立在對opLog的監聽,那么我們怎么確定一個補償的執行時機是合適的呢?補償一定要在事務有明確結果之后執行才有意義,那么什么時候能得到明確的事務執行結果?其實我們是無法確切的知道這個時間點的,但我們能夠有一個最低期望時間:不管一個事務成功或者失敗,它的周期都不能超過事務的超時時間。因此我們在發送opLog時需要設置opLog的delayTime>TransactionTimeout(如何確認transactionTimeout)來保證補償任務執行的時候本地事務一定執行完成。
從mns事務消息到分布式事務的啟發上面啰嗦的寫了一堆,看到這我們不妨對思考下mns事務消息解決的是業務系統(本地事務)與消息中間件之間的事務協同問題,如果是兩個業務系統之間的分布式事務如何實現?
好吧,如果堅持看到這,你可能覺得我標題黨了...那么我建議你再讀一下”mns事務消息“一文。
更多文章請訪問我的博客
轉載請注明出處
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70293.html
摘要:基礎深度學習概念備忘錄后端掘金基礎深度學習概念備忘錄翻譯自。否則,試想在你捧著某出版社剛剛翻譯出來的高效編程苦規范及相關文檔前端掘金官方規范歲程序員的獨家面試經歷閱讀掘金創業失敗后,在找工作。 基礎深度學習概念備忘錄 - 后端 - 掘金基礎深度學習概念備忘錄翻譯自DeepLearning Cheat Sheet。筆者還是菜鳥一枚,若有謬誤請多多賜教,另外如果希望了解更多機器學習&深度學...
摘要:但是服務器又確實是收到了這條消息的,只是給客戶端的響應丟失了,所以導致的結果就是扣款失敗,成功發貨。所有的半消息都會寫在為的半消息隊列里,并且每條半消息,在整個鏈路里會被寫多次,如果并發很大且大部分消息都是事務消息的話,可靠性會存在問題。 前言 得益于MQ削峰填谷,系統解耦,操作異步等功能特性,在互聯網行業,可以說有分布式服務的地方,MQ都往往不會缺席。由阿里自研的RocketMQ更是...
摘要:但是服務器又確實是收到了這條消息的,只是給客戶端的響應丟失了,所以導致的結果就是扣款失敗,成功發貨。既然消息的發送不能和本地事務寫在一起,那如何來保證其整體具有原子性的需求呢答案就是今天我們介紹的主角事務消息。 前言 得益于MQ削峰填谷,系統解耦,操作異步等功能特性,在互聯網行業,可以說有分布式服務的地方,MQ都往往不會缺席。由阿里自研的RocketMQ更是經歷了多年的雙十一高并發挑戰...
閱讀 1762·2021-11-24 09:39
閱讀 1690·2021-11-22 15:22
閱讀 1010·2021-09-27 13:36
閱讀 3243·2021-09-24 10:34
閱讀 3336·2021-07-26 23:38
閱讀 2635·2019-08-29 16:44
閱讀 978·2019-08-29 16:39
閱讀 1110·2019-08-29 16:20