如何構建故障容忍的分佈式系統

在前面我們講述基於資源利用率以及成本的權衡, 大部分情況下將會採用廉價且不可靠的組件來構建我們的分佈式系統, 比如異步網絡模型的無界延遲、時鐘漂移以及進程暫停是現實中存在且不可避免的問題, 那麼在實踐中是如何去構建一個故障容忍的分佈式系統呢? 今天聊聊我的思考.

Fencing Tokens 案例

這裏我舉一個在上一篇中我們談到獲取租約 ID 的例子, 其中由於發生 STW 導致寫入同一份數據存在衝突而使文件發生損壞, 如下: 

那麼這裏我們仔細思考下, 導致我們文件發生故障的根本原因是什麼呢? 在上圖我們可以知道是兩個客戶端都持有對相同文件數據的寫入鎖並能夠正常寫入數據, 但是在 Storage 層並沒有一個機制讓它知道對於操作相同文件數據到底該以什麼機制爲準.

那麼該怎麼去解決這個問題, 在這裏我們會採用 Fencing Tokens 機制, 即在獲取鎖的同時引入一個 Token, 這個 Token 是唯一且具備單調遞增的機制, 實現 Token 的方式我們可以採用 google 的 TrueTime 的時間戳或者是邏輯時鐘實現. 這樣當客戶端往 Storage 寫入數據的時候會攜帶對應的 Token 給到 Storage 並告訴他以最新的 Token 爲準, 攜帶的 Token 小於已持久化的 Token 直接拒絕寫入請求, 如下:

聊到這裏我們回到現實, 仔細思考下上面的故障我們業務層面能夠容忍嗎? 好, 我們再換個問題, 上述的 Lock Service 如果在某個時間段 T 不可用, 然後又恢復可用再次提供正常獲取鎖的服務響應, 那麼這個時候我們再思考下, 這個時間段 T 由於鎖服務發生宕機導致故 Client 端一直無響應, 那麼對於這個故障我們業務層面能夠容忍嗎?

Safety & Liveness

通過上述的 Fecning Tokens 例子, 我們可以看到 Lock Service 爲鎖機制提供一個生成 Tokens 的算法屬性:

在上述的算法屬性中, 唯一性以及單調有序性是分佈式系統的 Safety 屬性, 而可用性是指分佈式系統的 Liveness 屬性. 安全性通常被定義爲 “不會發生糟糕的事情”,而活性則被定義爲“最終會發生好的事情”。然而,最好不要對這些不正式的定義過度解讀,因爲“好” 與“壞”的含義是主觀的。安全性和活性的實際定義是精確且基於數學的:

這個時候我們再回到上述的例子, 我們要設計一個 Lock Service 的分佈式系統, 我們要優先保證 safety 屬性, 即在設計上要保證 Tokens 的生成具備唯一性以及單調有序性的情況下, 再考慮我們的可用性, 因爲對外不可用並不影響數據文件被損壞的情況, 因此這裏我們構建一個具備故障容忍的 Lock Service 服務, 這裏的故障容忍是指能夠容忍服務的不可用, 但在實際運行中, 我們的服務大部分時候都是可用的, 因爲故障總是能夠在有限時間 T 恢復回去的.

分佈式抽象系統模型

通過上述例子, 我們的分佈式系統問題可以通過制定對應的算法策略來解決. 比如我們要構建一個具備故障容忍的分佈式系統, 那麼我們設計的算法就需要容忍對應的故障, 算法並不依賴於軟硬件的配置細節, 而是通過將分佈式系統抽象爲一個系統模型來將各類故障進行形式化, 並基於系統模型的假設前提下考量算法設計的正確性, 即滿足安全性以及活性屬性. 一般地, 我們會將分佈式系統抽象爲以下兩大類系統模型:

基於時間假設的系統模型

基於節點故障的系統模型

之前在架構建模曾講過, 模型只是我們對現實世界的抽象, 是一項用於輔助我們在設計系統過程中識別問題複雜度的工具. 比如上述故障恢復模型的算法, 如果我們將數據存在在內存中, 那麼當其中的節點服務發生故障時候, 我們的數據就消失了; 

如果我們將數據存儲磁盤中, 那麼當磁盤也發生故障的時候怎麼辦呢? 可能我們會採用 RAID 陣列磁盤來或者使用 SAN、NAS 等來保證. 但是即便我們給出策略保證數據可靠性, 我們也會面臨着數據的一致性問題, 而數據一致性問題又可以拆分強一致性以及弱一致性 (或者稱最終一致性), 在這裏我把強一致性歸爲屬於安全性屬性, 而弱一致性歸爲活性屬性.

總結

因此, 區分安全性以及活性屬性有助於我們應對複雜的分佈式系統模型, 因爲我們在構建一個具備故障容忍的分佈式系統過程中必須要識別到哪些故障是我們業務層面是無法接受容忍的, 哪些故障是允許我們接受容忍的, 這就要求我們在進行架構設計過程能夠識別到系統的安全性以及活性屬性, 並在兩者之間進行權衡取捨然後做出對應的架構決策.

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/B-SqaL2HHnxqInePnMnbhQ