分散式檔案系統的容錯遵循前面章節討論過的一般原則;如前所述,許多情況下靠複製來建立容錯的伺服器群組。本節聚焦於分散式檔案系統容錯中的幾個特殊議題。
處理拜占庭失效#
容錯討論常忽略的一個問題是:伺服器可能出現任意(arbitrary)失效——多數系統並不考慮拜占庭失效(Byzantine failure)。除了複雜度之外,忽略它的原因在於必須對執行環境做很強的假設,特別是通訊延遲有界——這在實際環境並不現實。為此,卡斯楚(Miguel Castro)與里斯科夫(Barbara Liskov)設計了一套能在網際網路這類網路上運作的拜占庭容錯解法。這個協定可以(也已經)直接應用於分散式檔案系統,特別是基於 NFS 的系統,當然也有其他應用。
基本構想:部署主動複製(active replication),建立一組有限狀態機,讓其中未故障的行程以相同順序執行操作。假設同時最多 k 個行程故障:
- 用戶端把操作送給整個群組,接受至少 k+1 個不同行程回傳的相同答案。
- 要防護拜占庭失效,伺服器群組必須至少有 3k+1 個行程。
困難之處在於確保未故障行程以相同順序執行所有操作。簡單的辦法是指定一個協調者(coordinator),為每個請求附上序號來序列化所有操作——問題當然是協調者自己可能故障。
視圖與法定數#
麻煩正是從協調者故障開始。與虛擬同步(virtual synchrony)非常相似,行程會經歷一系列視圖(view):每個視圖中成員對「哪些行程未故障」有共識,當現任 master 看似故障時就發起視圖變更(view change)。偵測方式:假設序號是連號發出的,出現空隙或操作逾時就可能表示有問題。行程可能誤判需要安裝新視圖,但這不影響系統的正確性。
協定的重要部分依賴請求能被正確排序,為此使用法定數(quorum)機制:行程收到「在視圖 v 中以序號 n 執行操作 o」的請求時,把它送給所有其他行程,等到至少 2k 個其他行程確認看過同一請求為止——如此取得大小 2k+1 的 quorum。這樣的確認稱為法定數證書(quorum certificate),本質上表示已有足夠多的行程存了同一請求,可以安全繼續。
協定的五個階段#
整個協定由五個階段構成:
- request:用戶端把請求送給整個伺服器群組。
- pre-prepare:master 收到請求後,群播一個序號,讓對應操作能被正確排序。
- prepare:各 slave 副本若接受 master 提議的序號,就把接受群播給其他行程,確保該序號獲得 quorum 認可。
- commit:達成協議後所有行程互相通知並執行操作。
- reply:用戶端終於看到結果。

圖 11-26:拜占庭容錯中的各個階段。
為什麼 prepare 之後還需要 commit?prepare 結束時「所有行程對請求排序已有共識」只在同一視圖內成立:若中途發生視圖變更,不同行程可能把同一序號指派給不同操作(在不同視圖中指派)。commit 階段讓每個行程告訴其他人「我已把該請求連同當前視圖存入本地日誌」——即使之後要從當機中回復,行程也能確知某序號是在哪個視圖中指派給誰的。
已提交的操作在未故障行程看到相同的 2k 個 commit 訊息(且與自身意圖相符)後即可執行——又是一個 2k+1 的 quorum;當然,序號較小的待決操作要先執行。切換到新視圖基本上沿用虛擬同步的視圖變更:行程需要送出它所知的 pre-prepare 訊息,以及前一視圖收到的 prepare 訊息。
這個協定已為一個基於 NFS 的檔案系統實作,包含各種重要最佳化與精心設計的資料結構;另有一種包裝器(wrapper)能讓既有(legacy)應用納入拜占庭容錯。
點對點系統的高可用性#
點對點系統的可用性受到特別關注。乍看之下複製檔案就能輕鬆保證可用性;問題在於節點的不可用率太高,這種簡單推理不再成立。高可用性的關鍵解法是冗餘(redundancy),就檔案而言有兩種基本方法:複製(replication)與抹除碼(erasure coding)。
抹除碼是知名技術:把檔案切成 m 個片段,再重新編碼成 n > m 個片段;關鍵性質是任意 m 個編碼片段就足以重建原檔案。此時冗餘因子為 r_ec = n/m。設節點平均可用率為 a、要求的檔案不可用率為 ε,就需要保證至少 m 個片段可用。
相較之下,複製檔案的不可用率完全取決於所有 r_rep 份複本同時不可用的機率;假設節點離開彼此獨立且同分布,即 1 − ε = 1 − (1 − a)^r_rep。經過一些代數運算與近似,可以把兩者的差異表達為比值 r_rep/r_ec 與節點可用率 a 的關係(以 m = 5 為例繪出曲線)。

圖 11-27:比值 r_rep/r_ec 作為節點可用率 a 的函數。
結論:**在所有情況下,抹除碼需要的冗餘都比單純複製少。**換言之,在節點頻繁來去的點對點網路中,用複製來提升可用性,從儲存角度看不如抹除碼有效率。
有人會說磁碟容量早已過剩,省儲存無關痛癢。但要意識到維護冗餘會產生通訊:較低的冗餘度省的是頻寬。當節點是經非對稱 DSL 或 cable 上網的使用者機器(上行常只有幾百 Kbps)時,這項效能收益格外重要。