業務背景:
商戶提交表單資料至旺鋪(deco專案,以下皆稱為deco),deco需要接入poi系統進行裝修內容的人工審核,詳細流程見下圖。
店鋪裝修審核狀態在deco系統和poi系統之間不一致,下圖中1,2,3步提交流程會出現同一次提交審核流在deco系統中的裝修狀態為未裝修,而在poi系統為審核中。同樣在4,5,6步驟的審核**過程也會有同類的狀態不一致問題。兩塊問題都是同一技術問題,本文只以1,2,3步提交過程為例進行分析解決。
從業務中抽離出來,問題的核心原因可用下圖流程模型來描述。
系統a的某個業務功能包含兩步操作,第一步把資料寫入a系統本地庫,第二步遠端呼叫系統b,這兩步操作在a系統用乙個資料庫事務來包裝。偽**如下:
1第一步有兩種結果成功、失敗,第二步則有3種結果成功、失敗、超時,其中導致超時原因可能是網路中斷,也可能是b系統服務異常。那麼我們根據兩步驟的執行結果情況來分別分析一下是否會導致a、b系統之間的資料不一致。$db->begain();2//
第一步操作本地資料庫
3$res = $db->update($sql_a);4
if (!$res) 8
//第二步遠端呼叫b系統
可得當第一步執行成功,第二步遠端呼叫超時時,a系統事務會回滾,那麼就發生a、b系統資料不一致的情況,a庫中寫入失敗,但是b庫中卻成功寫入。我們習慣於使用關係型資料庫事務的acid特性來達到一致性的目的,但是當事務中發生跨系統的呼叫時acid就無效了,只從資料庫層面來看,跨系統就意味著同乙個業務存在多個資料副本,對應著不同的資料庫例項,而且分布在不同的機器上,而關係型資料庫的事務只是針對同乙個庫的同乙個connection而言的。
我們先重新認識一下什麼是一致性?首先想到的是關係型資料庫事務,又會想到最經典的甲給乙轉錢的例子,事務的四大基本特性acid保證了甲賬戶扣錢和乙賬戶入錢同時發生或同時不發生,其中的c特性就是指一致性,它是指資料庫事務不能破壞關係資料的完整性以及業務邏輯上的一致性。在web2.0之前大部分**或者專案都是單系統,對應底層儲存也只是單資料庫,所以使用資料庫本身的事務特性就滿足了一致性。
但是隨著網際網路使用者和資料量的指數級增長,對於每個系統的計算能力、吞吐量以及響應速度的要求都大大提高,於是單節點伺服器肯定滿足不了要求,所以都在考慮拆分和系統擴充套件性,無論是經過水平拆分還是垂直拆分,單機系統就變成了分布式系統,分布式系統就肯定存在某節點或者網路故障的情況,之前說的事務的acid中的強一致性就無法保證。
再回到我們的問題上來,poi系統其實就可以理解為垂直拆分出的乙個微服務,deco呼叫poi的提交審核介面就是分布式系統之間的呼叫,但是deco中仍然用關係型資料庫的事務來達到強一致性的目的,根據cap理論,分布式系統的一致性、可用性、分割槽容錯性不可能同時得到滿足,只能滿足其中兩個,而分布式系統的分割槽容錯性都需要得到滿足,所以就需要在一致性和可用性之間進行取捨。deco的這種實現其實就是為了保證一致性,而犧牲了可用性。
而對於現在的系統而言,可用性是至關重要的必須要保證,要做到即使poi系統出現偶爾的網路故障或者超時,也盡可能不要使用者的一次提交失敗掉。
再來了解乙個概念base理論,base理論是cap理論的一種實現,它對分布式系統的一致性和可用性不可兼得的問題提出了一種方案,即基本可用和最終一致是目標。既然提到了強一致性和最終一致性,再介紹一下業界對一致性的分層次定義。
對上面幾段分析的總結就是:關係型資料庫的事務可以滿足單系統的強一致性,大部分分布式系統只能把最終一致性作為追求。而我們的deco和poi系統顯然也是應該追求最終一致性,因為對於poi和deco之間裝修審核資料出現短時間的不一致是完全可以接受的。
基於上述理論,我們可以有以下兩種方案來達到可用性和最終一致性:
解耦,非同步任務處理,由原來同步呼叫poi系統變為非同步呼叫,將deco系統資訊入庫和呼叫poi建立審核任務這兩個操作分開。
deco系統收到使用者請求之後先資訊入庫,然後在本地資料庫同時新建乙個任務(任務初始狀態為待執行),當呼叫poi完成之後該任務改為已經執行,資訊入庫和建立任務在同乙個資料庫事務下。
後台定時指令碼來執行待執行狀態的任務。
如果非同步呼叫poi返回失敗,則需要對之前入庫的資訊進行回退。
如果非同步呼叫poi遇到網路問題或者超時,則考慮重試機制,注意重試機制要避免重複提交,可採取在deco系統重試前確認 或者 在poi系統保證介面的冪等性。
方案二、
引入訊息佇列,相當於對方案一的公升級版。
deco系統為訊息生產者,poi系統為訊息消費者。
生產者接收到使用者請求,業務資料處理入庫,然後寫入一條任務到訊息佇列,並且要新建一張訊息狀態表用於記錄訊息的執行狀態,以上三個操作要在同乙個本地事務中進行。其實也可以在業務表增加乙個字段用來表示訊息執行狀態,這樣有乙個缺點就是生產訊息和本身業務處理發生耦合,但是可以接受,因為既然放在乙個事務中耦合就不可避免。
消費者取出一條訊息,進行業務處理,處理完成後需要告訴deco系統訊息執行結果,成功或者失敗,如果失敗需要重新把訊息寫入佇列,注意這裡說的失敗並不是業務處理的正常返回「失敗」狀態,而是由於一些異常原因導致業務處理沒有正常完成的情況。poi系統方需要重試時才會傳送失敗的通知。
要保證最終一致性,該方案還有乙個關鍵點是訊息佇列本身的可靠性和寫資料庫和寫訊息佇列事務的一致性。比如**的notify的兩階段提交機制就是為了滿足這一點。也可以參考糯公尺技術文章平台有一篇技術文章《輕量級高可靠訊息佇列》
對於單機單庫系統,資料一致性可通過關係型資料庫的事務來滿足,而且acid特性中的c是指強一致性,各資料庫本身都支援,而且很成熟。
分布式系統則需要以base理論作為指導,即以基本可用性和最終一致性作為目標。
遠端rpc呼叫是一致性問題主要原因,非同步解耦+訊息佇列可作為分布式系統滿足最終一致性的優秀方案。
分布式系統一致性問題解決實戰
業務背景 商戶提交表單資料至旺鋪 deco專案,以下皆稱為deco deco需要接入poi系統進行裝修內容的人工審核,詳細流程見下圖。店鋪裝修審核狀態在deco系統和poi系統之間不一致,下圖中1,2,3步提交流程會出現同一次提交審核流在deco系統中的裝修狀態為未裝修,而在poi系統為審核中。同樣...
分布式一致性問題
典型情況 三個副本構成乙個group 1.強一致性 所有的副本更新成功才返回。同時,p向s1 s2同步的過程,可以進行優化,借鑑gfs的流水線複製方式 p s1 s1 s2 以便充分利用每個node的頻寬資源。2.最終一致性 在經過乙個不一致視窗後,副本最終處於一致的狀態。如上圖是一種簡單的最終一致...
分布式一致性問題。
在電腦科學領域,分布式一致性問題是乙個相當重要,且被廣泛探索與論證的問題,通常存在於諸如分布式檔案系統 快取系統和資料庫等大型分布式儲存系統中。什麼是分布式一致性?分布式一致性分為哪些型別?分布式系統達到一致性後將會是乙個什麼樣的狀態?如果失去了一致性約束,分布式系統是否還可以依賴?如果一味地追求一...