考慮到容錯對任何分散式系統都是根本要求,協調式系統——包括基本的發佈/訂閱系統與支援生成式通訊的系統——受到的容錯關注竟相對少,有些令人意外。多數情況下,注意力集中在確保資料遞送的高效可靠性,本質上就是保證可靠通訊;當中介軟體還被期望儲存資料項(生成式通訊的情況),才會有些心力投入可靠儲存。以下分別細看這兩種情況。

可靠的發佈/訂閱通訊#

在「發佈的資料項只與在線訂閱者比對」的協調式系統中,可靠通訊扮演關鍵角色。此時容錯最常透過在發佈/訂閱軟體底層實作可靠多播系統來達成。一般要處理的議題有二:其一,無論內容式路由如何進行,都要建立一條可靠的多播通道;其二,要處理行程容錯。以下看 TIB/Rendezvous 如何處理這些問題。

範例:TIB/Rendezvous 的容錯#

TIB/Rendezvous 假設底層網路的通訊設施先天不可靠,並以下列機制補償:

  • 保留與重傳:rendezvous daemon 向其他 daemon 發佈訊息後,會把該訊息保留至少 60 秒。發佈時,daemon 為訊息附上一個(與主題無關的)序號;接收端 daemon 由序號即可偵測漏收(記得訊息會遞送給所有 daemon),並要求發佈端 daemon 重傳。
  • 仍可能遺失:這種可靠通訊無法完全防止訊息遺失——例如要求重傳的訊息已發佈超過 60 秒,發佈端 daemon 一般已無能為力。正常情況下,發佈與訂閱應用程式會被告知發生了通訊錯誤,錯誤處理交由應用程式

TIB/Rendezvous 的通訊可靠性大量倚賴底層網路提供的可靠性;它也在(不可靠的)IP 多播之上提供可靠多播,採用的是傳輸層多播協定 Pragmatic General Multicast(PGM)(Speakman et al., 2001)。

PGM 不保證多播訊息最終送達每個接收者,而是靠接收者自行偵測漏收

  • 漏收的接收者沿著以發送者為根的多播樹反向路徑送出重傳請求(NAK)。中介節點若快取了被請求的訊息,就地處理重傳;否則把 NAK 繼續往發送者方向轉發。發送者是重傳的最終負責者。
  • NAK 抑制:中介節點若收到多個針對同一訊息的重傳請求,只往發送者轉發一個——盡量讓只有單一 NAK 抵達發送者,避免回饋爆炸(feedback implosion)(第 8 章討論可靠多播的可擴展性時談過這個問題)。
  • 選擇性重傳:PGM 記住 NAK 從接收者到發送者所經過的路徑;發送者重傳時,訊息只多播給曾請求重傳的接收者,已成功收到的接收者不會被無用的重傳打擾。

圖 13-16:PGM 的原理。(a) 訊息沿著多播樹送出。(b) 重傳請求(NAK)沿反向路徑送回發送者,並在中介節點被抑制。

認證訊息遞送#

在基本可靠性方案與 PGM 之外,TIB/Rendezvous 還以**認證訊息遞送(certified message delivery)**提供進一步的可靠性:

  • 行程使用特殊的通訊通道收發訊息;通道附帶一個稱為**帳簿(ledger)**的設施,記錄已送出與已接收的認證訊息。
  • 想接收認證訊息的行程,需向這類訊息的發送者註冊。註冊讓通道得以處理 rendezvous daemon 不支援的進一步可靠性議題;這些大多對應用程式隱藏,由通道的實作處理。
  • 當帳簿以檔案實作時,即使行程故障也能提供可靠遞送:接收行程崩潰後,它錯過的所有訊息都存放在發送端的帳簿中;復原後,接收者只需聯絡帳簿並要求重傳錯過的訊息。

以行程群組遮蔽行程故障#

為了遮蔽(mask)行程故障,TIB/Rendezvous 提供簡單的行程自動啟用/停用機制。這裡「活躍(active)」行程正常回應所有進來的訊息,「非活躍(inactive)」行程則否——它是一個執行中、但只處理特殊事件的行程。

  • 行程可以組成群組,每個行程有唯一的位階(rank)。位階由(人工指定的)權重決定,同群組中不得有兩個行程同位階。
  • 對每個群組,TIB/Rendezvous 會設法維持群組特定數量的活躍行程,稱為該群組的活躍目標(active goal)。許多情況下活躍目標設為 1,此時與群組的所有通訊就化約為第 7 章討論過的主要式(primary-based)協定
  • 活躍行程定期向群組所有成員送出心跳(heartbeat)訊息表明自己仍在運作。一旦心跳缺失,中介軟體自動啟用目前非活躍行程中位階最高者;啟用透過回呼(callback)每個群組成員都應實作的 action 操作完成。同樣地,先前崩潰的行程復原並轉為活躍後,目前活躍行程中位階最低者會被自動停用。
  • 非活躍行程要能接手,必須先與活躍行程保持一致。簡單做法:讓非活躍行程訂閱與其他群組成員相同的訊息,照常處理進來的訊息,但從不發佈任何反應

這個方案性質上近似主動複製(active replication)

共享資料空間中的容錯#

處理生成式通訊時,事情更複雜。如 Tolksdorf 與 Rowstron (2000) 所指出:一旦要把容錯納入共享資料空間,解法往往變得極沒效率,以致只有集中式實作可行。此時採用的是傳統解法:中央伺服器搭配簡單的主要—備援(primary-backup)協定備份,並結合檢查點(checkpointing)

另一種做法是更積極地部署複製,把資料項的副本放到各機器上。GSpace 採用了這種方式——基本上沿用它為效能而複製的同一套機制。為此,每個節點計算自身的可用性(availability),再用來計算單一(被複製的)資料項的可用性(Russello et al., 2006):

  • 節點定期把時間戳記寫入持久儲存,藉此推算自己在線與離線的時間。可用性以**平均故障間隔時間(mean time to failure, MTTF)平均修復時間(mean time to repair, MTTR)**表示:節點檢視記錄的時間戳記,算出故障間隔的平均值,得出可用性 MTTF / (MTTF + MTTR)。
  • 由於必須定期記錄時間戳記,崩潰時刻只能以最後一筆時間戳記作為最佳估計,因此算出的可用性是悲觀的——實際崩潰時刻會比估計稍晚。另外,也可以不從頭取平均,只考慮最近 N 次崩潰。
  • 在 GSpace 中,每種資料項型別都有一個負責計算該型別可用性的主節點(primary node)。若資料項複製於 m 個節點,其可用性由這 m 個節點各自的可用性 ai 計算而得。

圖 13-17:一個經歷故障的節點的時間軸。

只要同時考慮資料項要求的可用性與所有節點的可用性,主節點就能算出滿足可用性需求的最佳放置;此外也能納入其他因素(如頻寬用量與 CPU 負載)。這些因素波動時,放置也可能隨時間改變。