分佈式學習(三)-分佈式系統一致性

產生原因:

互聯網時代信息量巨大、需要計算能力巨大,不但對用戶響應速度要求快,而且吞吐量指標也要向外擴展(既:水平伸縮),於是單節點的服務器無法滿足需求,服務節點開始池化。爲了有序、合理的分配任務,進行有效的管理,於是開始拆分。分水平拆分和垂直拆分。

  • 水平拆分:同一個功能由於單機節點無法滿足性能需求,需要擴展成多個節點,多個節點具有一致的功能。一個節點服務一部分的請求量,共同處理大規模高併發的請求。
  • 垂直拆分:按功能拆分,把一個複雜的功能拆分成若干個單一簡單的元功能,拆分的元功能組合在一起和未拆分前的功能一致。
  • 水平和垂直拆分後多個元功能的模塊和水平拆分中的多個節點,爲了保證他們的信息一致。

強一致性:

  • 利用關係型數據庫的強一致性原則,升級硬件。拆分時相關業務放到一個數據庫分片。如果業務無法滿足,則通過記錄事務的中間臨時狀態,最終實現一致性。

最終一致性:

Write-Ahead Log:每一步操作都先寫上日誌,如果遇到問題,可以讀取日誌按照步驟恢復,並且繼續執行未完成的工作,最後達到一致。

 

分佈式一致性協議:

國際開放標準組織Open Group定義了DTS(分佈式事務處理模型),模型中包含4個角色:應用程序、事務管理器、資源管理器、通信資源管理器四部分。事務處理器是統管全局的管理者,資源處理器和通信資源處理器是事務的參與者。

下面介紹兩階段提交協議,三階段提交協議和阿里巴巴提出的TCC,都是根據DTS的思想演變出來的。

兩階段提交協議:把分佈式事務分爲兩個過程,一個準備階段,一個提交階段,準備階段和提交階段都是由事務管理器發起。

  • 準備階段:協調者向參與者發起指令,參與者評估自己的狀態,如果參與者評估指令可以完成,參與者會寫redo或者undo日誌,鎖定資源,然後執行操作,但是不提交。
  • 提交階段:如果每個參與者都明確返回準備成功,也就是預留資源和執行操作成功,協調者向參與者發起提交指令,參與者提交資源變更的事務,然後釋放鎖定的資源。如果任何一個參與者明確返回準備失敗,協調者向參與者發起中止指令,參與者取消已經變更的事務,執行undo日誌,釋放鎖定的資源。

示意圖如下:

該協議已知存在的問題:

1、阻塞,對於任何一次指令必須收到明確的響應,纔會繼續下一步。

2、單點故障,協調者發送一個提交指令後宕機,提交指令僅僅被一個參與者接受,並且參與者接受後也宕機,新選舉的協調者無法處理這種情況。

3、腦裂問題。協調者發送提交指令,由的參與者接受到執行了事務,有的參與者沒有接受到事務,就沒有執行事務,造成多個參與者不一致。

三階段提交協議:通過超時機制解決了二階段提交協議的阻塞問題。

  • 詢問階段:協調者詢問參與者是否可以完成指令,協調者只需要回答是還是不是,而不需要做真正的操作,這個階段超時導致中止。
  • 準備階段:超時導致成功(超時,協調者和參與者都繼續提交事務,默認成功)。
  • 提交階段:

示意圖入下:

該協議已知存在的問題:

1、一旦超時,系統仍然會存在不一致,相比兩階段提交協議不會發生阻塞和永遠鎖定資源。

2、仍然存兩階段提交協議存在的單點問題和腦裂問題。

TCC:

示意圖如下:

該協議已知存在的問題:

1、cancel的時候有的參與者接受到指令,有的參與者未接受到指令,最終造成數據不一致。

保證最終一致:

在大規模高併發服務化系統中,如果使用兩階段提交協議和三階段提交協議,能解決系統間一致性的問題,但實現比較複雜,成本比較高,性能並不能得到保證。相比TCC協議比較容易實現,但是會增加耦合性。

在現實系統中,底線是要保證最終一致性,不需要實現專業、複雜的一致性協議,介紹幾種簡單、粗暴、有效的方案。

  • 查詢:每個服務提交一個查詢接口,向外輸出外部執行操作執行的狀態。服務的使用方通過調用查詢接口,根據得到的狀態決定做不同的操作。實現查詢每個服務操作必須要有唯一的流水號,比如流水號,訂單號。
  • 補償:有了查詢模式,我們能獲得具體的操作所處的狀態,如果整個操作處於不正常的狀態,則需要修改操作中有問題的子操作。爲了保證系統的最終一致性而作的操作都叫補償。根據發起形式分爲:自動恢復,通知運營,通知技術
  • 異步確保:對響應時間要求不高的請求通常通過異步的方式處理,處理後通知系統通知使用方。此方案可以對高併發流量削峯,常見的有:電商中的物流,配送,短信和郵件提醒。實踐中,將異步任務持久化到數據庫,通過定時任務執行未完成的任務,最終每個任務都被成功執行。
  • 定期校對。
  • 可靠消息模式:爲了解耦,利用消息隊列。2種模式。

1)、發送消息前,把消息持久化到數據庫,並標記爲待發送,然後發送消息,如果消息發送成功,將消息改爲已發送,定時任務定期從數據庫撈出未發送的消息,將消息重新發送。

2)、持久消息的數據庫是獨立的,並不耦合在業務系統中。發送消息之前,先發送一個預消息給某一個第三方的消息管理器,消息管理器將其持久到數據庫,並標記狀態爲待發送,發送成功後,標記消息爲發送成功。定時任務定時從數據庫撈取一定時間內未發送的消息,回查業務系統是否要繼續發送,根據查詢結果來確定消息的狀態。

本文完。

參考:https://www.jianshu.com/p/1156151e20c8

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章