內容來源:2017年12月2日,華為資深架構師王啟軍在“NJSD網際網路架構峰會”進行《Cloud Native架構一致性問題及解決方案》演講分享。IT 大咖說(微信id:itdakashuo)作為獨家視訊合作方,經主辦方和講者審閱授權釋出。
閱讀字數:2092 | 6分鐘閱讀
嘉賓演講視訊及PPT回顧:suo.im/tPQXc
摘要
在開發或軟體架構的過程中,經常會遇到一致性的問題,那麼如何去解決權衡。我們先從理論入手,然後進一步討論強一致性和最終一致性的解決方案。
基礎理論
Cloud Native的組成
關於這個概念很多人都有不同的看法,我認為Cloud Native主要是由架構、組織、工程三部分組成的。大部分公司可能主要是關注架構部分,其實組織方面也是非常重要的,它的價值在於能夠實現更快的速度、更好的使用者互動體驗以及更穩當的系統。
Cloud Native-架構
Cloud Native架構主要包含兩部分,一個是基礎設施這塊,另一個是微服務架構方面。圍繞著微服務又擴充套件出了可用性、一致性以及擴充套件性部分。
一致性的分類
在學術界一般將一致性分為兩類,一類是以資料為中心,一類以使用者為中心。以資料為中心的,無論有多少個節點都是從整體上來看一致性。而以使用者為中心,是從客戶端的節點來看待一致性的。
嚴格一致性
嚴格一致性要求任何寫操作都能立刻同步到其他所有程式,任何讀操作都能讀取到最新的修改。比如說有三個節點,當某一個節點的資料a變成1的時候,另外兩個節點的a就需要同步改變。
順序一致性
嚴格一致性需要有一個全域性時鐘才能實現,但是這個全域性時鐘是很難實現的。於是順序一致性放棄了它,轉而改用分散式邏輯時鐘來實現。
順序一致性是指所有的程式以相同的順序看到所有的修改,讀操作未必能及時得到此前其他程式對同一資料的寫更新,但是每個程式讀到的該資料的不同值得順序是一致的。
因果一致性
因果一致性是一種弱化的順序一致性,如果兩個資料之間存在因果關係,那麼在後續的所有操作都應該基於這一關係。所有的程式必須以相同的順序看到具有潛在因果關係的寫操作。不同程式可以以不同的順序看到併發的寫操作。
如何實現強一致性
兩階段提交
提到強一致性,相信大家首先想到的就是兩階段提交。也就是整個互動過程分為兩個階段。第一階段協調者先向參與者提問是否可以提交,同時鎖定資料,第二階段參與者提交。
這裡面存在幾個問題,第一階段鎖定資料之後,如果協調者掛掉了,將沒有角色去通知參與者是否應該提交,這個資料會被一致鎖定。如果第二階段參與者1提交成功,參與者2提交失敗,此時協調者不知道該如何處理,因為參與者1已經提交成功,外部可以訪問了。
三階段提交
三階段提交其實是把兩階段提交的第一階段分為了兩個階段,這是為了降低原來第一階段的死鎖的概率。三階段的第一階段在詢問是否提交的時候並沒有鎖定資料,而是在準備提交的時候才鎖定資料。
實際上使用三階段提交,效能上會有更多的消耗,互動會越來越多,可擴充套件性也很差。
如何實現最終一致性
除錯失敗怎麼辦
假設有一個服務M需要去呼叫另外的兩個服務A、B,在呼叫的過程中失敗了話,最常見的做法就是重試。這時就需要去考慮重試的次數、超時時間、間隔時間以及間隔時間的衰減度,而重試沒有做好的話就很容易造成系統的負擔。
改進方案
其實完全可以新增一個日誌,並且可以收集到遠端。通過收集系統收集到分散式檔案系統內,這樣就可以不斷的去檢測這個系統是否有問題。
還有一種解決方案——可靠事件,服務在呼叫失敗後,通過另一種方式將資料傳輸到訊息佇列,然後要被呼叫的服務去讀取訊息佇列。
對於最終一致性來說,要麼全部成功,要麼全部失敗。
如何保證寫後讀一致
這需要在寫訊息的同時,去寫一個事件日誌。如果一旦失敗的可以通過補償服務不斷的遍歷事件的這張表,最終拿到訊息再去傳送時間
長事務一致性
Sage事務模型
Sgae是一個比較早期的事務模型,它的核心思想是將一個長事務拆分為多個本地事務。而process manageer就是負責處理事務拆封的,然後再去呼叫不同的服務。
這是一個具體的事務處理流程,這裡面需要定時的去做檢查判斷是否失敗,失敗了就要傳送訊息,正向呼叫時寫回退日誌。
TCC
在做系統的時候你會發現服務是很容易的去擴充套件的,資料庫往往會出現瓶頸,那麼如何去平衡壓力,有很多的解決方案,TCC就是其中的一種。
TCC的優勢在於將資料庫的操作,放到業務層處理,平衡了資料庫的壓力。但同時也付出了一定代價,它增加了業務的複雜度,需要提供相應的Try、Confirm、Cancel介面,而且介面還是冪等性的。
如何保障冪等
第一種就是通過資料加鎖的方式,第二種是分散式鎖,不過這種鎖不能保障絕對一致性,第三種方案可以去做唯一約束,在唯一約束無效的情況下可以增加流水錶這也是第四種方案。