Azure Service Fabric 中的災害復原

提供高可用性的關鍵在於確保服務能夠承受所有不同類型的失敗。 這對於預料之外且無法控制的失敗而言特別重要。

本文描述一些常見的失敗模式,如果沒有未正確建立模型和管理,可能會造成嚴重損壞。 此外,本文也會探討發生災害時應採取的緩解措施和行動。 目標是發生失敗 (無論計劃性或非計劃性) 時,限制或排除停機或資料遺失的風險。

避免災害

Azure Service Fabric 的主要目標是幫助您將環境和服務建立模型,使常見的失敗類型不致於變成災害。

一般而言,有兩種類型的災害/失敗案例:

  • 硬體和軟體錯誤
  • 操作錯誤

硬體和軟體錯誤

硬體和軟體錯誤是無法預期的。 承受失敗最簡單的方法是跨硬體或軟體錯誤邊界執行更多服務複本。

例如,如果您的服務僅在一部機器上執行,則該機器的失敗即為該服務的災害。 有種簡單方式可以避免此災害,就是確保服務在多部機器上執行。 測試也有所必要,以確保某部機器的故障不會中斷執行中的服務。 容量規劃可確保能在其他地方建立取代用的執行個體,而且容量的減少不會多載剩餘的服務。

無論您想避免的故障類型為何,相同的模式皆可發揮作用。 例如,如果您擔心 SAN 故障,可跨多個 SAN 執行。 如果您擔心伺服器機架損失,可跨多個機架執行。 如果您擔心資料中心遺失,您的服務應該跨多個 Azure 區域、跨多個 Azure 可用性區域,或跨您自己的資料中心執行。

當服務跨越多個實體執行個體 (機器、機架、資料中心、區域) 時,您仍容易同時發生某些類型的失敗。 但是,特定類型的單一和甚至多個失敗 (例如,單一虛擬機器或網路連結失敗) 會自動加以處理,因此不再是「災害」。

Service Fabric 會提供機制來擴展叢集,以及將失敗的節點和服務救回。 Service Fabric 也允許執行服務的許多執行個體,以防止這些類型的非計劃性失敗轉變成真正的災害。

有一些原因會導致無法執行規模夠大的部署來涵蓋各種失敗。 例如,相較於您不願為相關失敗可能性付出的承擔,其可能需要更多硬體資源。 當您處理分散式應用程式時,跨地理位置距離的其他通訊躍點或狀態複寫成本可能造成無法接受的延遲。 每個應用程式繪製的此線條有所不同。

對於特定的軟體錯誤而言,此錯誤可能發生在您嘗試調整規模的服務中。 在這種情況下,更多複本無法預防災害,因為失敗條件在所有執行個體之間都是互相關聯的。

操作錯誤

即使您的服務遍布全球,具備許多備援,仍可能會遇到災難性的事件。 例如,有人可能意外地重新設定服務的 DNS 名稱,或直接將其刪除。

舉例來說,假設您的 Service Fabric 具狀態服務,而有人不小心刪除了該服務。 除非有其他緩解措施,否則該服務及其擁有的所有狀態會立即消失。 這些類型的操作災害 (「糟糕」情況) 恢復所需的緩解和步驟與一般未預期故障不同。

避免這些類型之操作錯誤的最佳方式是:

  • 限制對環境的操作存取。
  • 嚴格稽核危險的作業。
  • 實行自動化,避免手動或頻外變更,並且先根據環境驗證特定變更,然後再加以制定。
  • 確認破壞性作業是否為「軟性」。軟性作業不會立即生效,或是可以在一段時間內復原。

Service Fabric 會提供機制以避免操作錯誤,例如,為叢集作業提供 role-based 存取控制。 不過,大部分的操作錯誤需要投入組織化的心力以及其他系統。 Service Fabric 會提供機制以因應操作錯誤,最值得注意的是具狀態服務的備份與還原

管理故障

Service Fabric 的目標是自動管理失敗。 但是,為了處理某些類型的失敗,服務必須有其他程式碼。 基於安全性和商務持續性的原因,「不」應該自動解決其他類型的失敗。

處理單一故障

單一機器可能鑒於各種原因而故障。 有時其是硬體的原因,像是電源供應器和網路硬體失敗。 其他是軟體故障, 其中包含作業系統和服務本身的失敗。 Service Fabric 會自動偵測這些類型的失敗,例如機器由於網路問題而與其他機器隔離的情況。

無論服務類型為何,如果程式碼的單一複本因故失敗,執行單一執行個體會造成該服務停機。

若要處理任何單一失敗,最簡單的方式就是確保您的服務預設在多個節點上執行。 若為無狀態服務,請確定 InstanceCount 大於1。 若為具狀態服務,最小的建議是 TargetReplicaSetSizeMinReplicaSetSize 都設定為 3。 執行服務程式碼的多個複本可確保您的服務可自動處理任何單一失敗。

處理協調失敗

叢集中的協調失敗可能由於計劃性或非計劃性基礎架構失敗和變更,或計劃性軟體變更所致。 Service Fabric 會將發生協調失敗的基礎結構區域建立模型,做為「容錯網域」。 發生協調軟體變更的區域會建立模型做為「升級網域」。 如需容錯網域、升級網域和叢集拓撲的詳細資訊,請參閱使用叢集資源管理員描述 Service Fabric 叢集

在規劃應在何處執行服務時,Service Fabric 依預設會考慮容錯網域和升級網域。 根據預設,Service Fabric 會嘗試確保可跨數個容錯網域和升級網域執行服務,以便您的服務在發生計劃性或非計劃性變更時,仍保持可用。

例如,假設電源故障造成機架上的所有機器同時故障。 服務單一失敗的另一個範例是,容錯網域中有多個服務複本執行的許多機器出現損失。 這就是容錯網域和升級網域的管理為何對確保服務的高可用性如此重要。

當您在 Azure 中執行 Service Fabric 時,系統會自動管理容錯網域和升級網域。 在其他環境中則可能不會。 如果您要在內部部署中建置自己的叢集,請務必正確地對應及規劃您的容錯網域配置。

升級網域對於軟體將同時升級的模型化區域很有用。 有鑑於此,升級網域也經常定義計劃性升級期間刪除軟體的邊界。 Service Fabric 和您的服務升級皆遵循相同的模型。 如需輪流升級、升級網域的詳細資訊,以及進一步了解 Service Fabric 健康情況模型如何協助防止非預期的變更影響叢集和您的服務,請參閱:

您可以使用 Service Fabric Explorer 中提供的叢集對應,視覺化您的叢集配置:

Nodes spread across fault domains in Service Fabric Explorer

注意

失敗區域的模型化、輪流升級、執行服務程式碼和狀態的許多執行個體、確保您的服務執行於各容錯與升級網域之間的放置規則、還有內建的健康情況監視都只是 Service Fabric 提供的部分功能,可用來避免正常的運作問題和失敗變成災害。

處理同時發生的硬體或軟體故障

我們已討論單一失敗。 如您所見,只要讓更多的程式碼 (及狀態) 的複本保持在各容錯和升級網域中執行,無狀態和有狀態服務就能輕鬆處理它們。

也可能發生多個同時的隨機失敗。 這些更可能導致停機或實際災害。

無狀態服務

無狀態服務的執行個體計數表示需要執行中的執行個體數目。 當任何 (或所有) 執行個體失敗時,Service Fabric 會在其他節點上自動建立取代執行個體來回應。 Service Fabric 會繼續建立取代個體,直到服務恢復到所需的執行個體計數。

例如,假設無狀態服務具有的 InstanceCount 值為 -1。 此值表示一個執行個體應在叢集中的每個節點上執行中。 如果其中某些執行個體失敗,Service Fabric 將會偵測到服務不是處於其所需狀態,並會嘗試在遺漏執行個體的節點上建立執行個體。

具狀態服務

具狀態服務有兩種類型:

  • 具有持續狀態的具狀態。
  • 具有非持續狀態的具狀態。 (狀態儲存在記憶體中。)

從具狀態服務的失敗復原取決於具狀態服務的類型、服務擁有多少個複本,以及有多少個複本失敗。

在具狀態服務中,系統會在複本 (主要複本和任何作用中次要複本) 之間複寫傳入資料。 如果大部分的複本都會收到資料,則系統會將資料視為認可的「仲裁」。 (對於五個複本,三個複本將是仲裁。)這表示在任何時間點,至少會有一個具有最新資料的複本仲裁。 如果複本失敗 (假設 5 個中的 2 個),我們可以使用仲裁值來計算是否可以將其復原。 (因為剩下的三個複本仍正常運作,所以保證至少有一個複本會有完整的資料。)

當複本的仲裁失敗時,系統會將分割區宣告為處於「仲裁遺失」狀態。 假設分割區有 5 個複本,這表示至少有 3 個複本保證具有完整的資料。 如果複本 (5 個中的 3 個) 的仲裁失敗,Service Fabric 無法判斷剩餘的複本 (5 個中的 2 個) 是否有足夠的資料來還原分割區。 在 Service Fabric 偵測到仲裁遺失的情況下,其預設行為是防止對分割區進行額外寫入、宣告仲裁遺失,並等候複本的仲裁還原。

判斷具狀態服務是否發生災害,然後遵循三個階段進行管理:

  1. 判斷是否有仲裁遺失。

    當具狀態服務的大部分複本同時關閉時,就會宣告仲裁遺失。

  2. 判斷仲裁遺失是否為永久性的。

    大多數時候,失敗是暫時性的。 流程會重新啟動、節點會重新啟動、虛擬機器會重新啟動,以及網路分割區會進行修復。 不過,有時候失敗是永久性的。 失敗是否為永久性,取決於具狀態服務保存其狀態,還是只將其保留在記憶體中:

    • 對於非持續狀態的服務,單一仲裁或多個複本的失敗會立即導致永久性的仲裁遺失。 當 Service Fabric 偵測到具狀態非持續服務中的仲裁遺失時,會藉由宣告 (可能) 資料遺失,立即進行步驟 3。 繼續進行資料遺失是有意義的,因為 Service Fabric 知道沒有任何時間點等候複本復原。 即使它們復原,資料仍會因為服務的非持續性質而遺失。
    • 對於具狀態的持續性服務,仲裁失敗或更多複本會造成 Service Fabric 等待複本復原並還原仲裁。 這會導致任何寫入服務的受影響分割區 (複本集) 發生服務中斷。 不過,仍可能在降低一致性保證的情況下進行讀取。 Service Fabric 等待仲裁還原的預設時間是「無限的」,因為進行的是一個 (潛在的) 資料遺失事件,並帶有其他風險。 這表示,除非管理員採取動作來宣告資料遺失,否則 Service Fabric 不會繼續進行下一個步驟。
  3. 判斷資料是否遺失,並從備份進行還原。

    如果已宣告仲裁遺失 (自動或透過系統管理動作),Service Fabric 和服務會繼續進行,以判斷資料是否真的遺失。 此時,Service Fabric 也知道其他複本不會復原。 這是停止等待自行解決仲裁遺失時會作出的決定。 服務採用的最佳方法通常是凍結,並等待特定的管理介入處理。

    當 Service Fabric 呼叫 OnDataLossAsync 方法時,一律是因為「疑似」發生資料遺失。 Service Fabric 可確保此呼叫會傳遞至最佳剩餘複本。 這是進度最多的複本。

    我們總是說「疑似」發生資料遺失的原因是,仲裁遺失時其餘複本可能具有與主要複本相同的所有狀態。 不過,如果沒有與其相比的狀態,Service Fabric 或運算子確實沒有好方法可用。

    那麼,OnDataLossAsync 方法的典型做法是什麼?

    1. 實作會記錄已觸發 OnDataLossAsync,而且其會引發任何必要的系統管理警示。

    2. 通常,實作會暫停並等候進一步的決策,以及要採取的手動動作。 這是因為即使有備份可用,它們可能仍需要做好準備。

      例如,如果兩個不同的服務協調資訊,可能需要修改這些備份,以確保發生還原後,這兩個服務所關心的資訊是一致的。

    3. 通常,有一些來自服務的其他遙測資料或廢棄資料。 此中繼資料可能包含在其他服務或記錄中。 您可以視需要使用此資訊,來判斷主要複本是否有接收及處理備份中不存在或複製到此特定複本的任何呼叫。 這些可能需要先重新執行或新增到備份,才可進行還原。

    4. 此實作會將其餘複本的狀態與任何可用備份中包含的狀態進行比較。 如果您是使用 Service Fabric 可靠集合,則有可用的工具和流程來這樣做。 目標是查看複本內的狀態是否足夠,或查看哪個備份是否可能遺漏。

    5. 比較完成後,以及還原完成 (如有需要) 後,如果進行了任何狀態變更,則服務程式碼應傳回 true。 如果複本判斷其是最佳可用的複本狀態,而且未進行任何變更,則程式碼會傳回 false

      true 值表示任何「其他」剩餘複本現在可能與此複本不一致。 將會卸除這些複本,並從此複本重建。 false 值表示未進行任何狀態變更,因此其他複本可以保持現有狀態。

在生產中部署服務之前,服務製作者實踐潛在的資料遺失和失敗案例至關重要。 若要防止資料遺失的可能性,務必定期針對任何具狀態服務備份狀態至異地備援存放區。

您也必須確定您有還原狀態的能力。 由於許多不同服務的備份是在不同時間採用,因此您需要確保還原後,服務彼此間的檢視達到一致。

例如,假設其中一項服務產生數字,並儲存該數字,然後將其傳送至另一個也會儲存該數字的服務。 還原後,您可能會發現第二個服務具有數字,但第一個服務沒有數字,因為其是備份而不包含該作業。

如果您發現剩餘複本不足以在資料遺失案例中繼續進行,而且您無法從遙測資料或廢棄資料重建服務狀態,則備份的頻率將決定您的最佳還復原點目標 (RPO)。 Service Fabric 會提供許多工具,以測試各種失敗情況,包括需要從備份還原的永久仲裁和資料遺失。 這些案例會併入作為 Service Fabric 中可測試性工具的一部分,由錯誤分析服務管理。 如需這些工具和模式的詳細資訊,請參閱錯誤分析服務簡介

注意

系統服務也可能遭受仲裁遺失。 影響是有問題服務特有的。 比方說,具名服務的仲裁遺失將會影響名稱解析,而容錯移轉管理員服務的仲裁遺失會封鎖新服務的建立與容錯移轉。

Service Fabric 系統服務會依照相同的模式,為您的服務進行狀態管理,但不建議您嘗試將其從仲裁遺失中移出並移入潛在的資料遺失。 相反地,建議您尋求支援,以找出以您情況為目標的解決方案。 通常最好是等到關閉的複本返回為止。

針對仲裁遺失進行疑難排解

複本可能由於暫時性失敗而間歇地關閉。 等候一段時間,因為 Service Fabric 會嘗試將其啟動。 如果複本已關閉,超過預期的持續時間,請遵循下列疑難排解動作:

  • 複本可能損毀。 請檢查複本層級的健康情況報告和您的應用程式記錄。 收集損毀傾印,並採取必要動作來復原。
  • 複本流程可能會變成沒有回應。 檢查您的應用程式記錄以確認此情況。 收集流程傾印,然後停止沒有回應的流程。 Service Fabric 將會建立取代流程,並嘗試將複本帶回。
  • 裝載複本的節點可能已關閉。 請重新啟動基礎虛擬機器以將節點啟動。

有時候,可能無法復原複本。 例如,磁碟機故障或機器實際上沒有回應。 在這些情況下,必須告知 Service Fabric 不要等待複本復原。

如果潛在資料遺失無法接受使服務連線,請「勿」使用這些方法。 在此情況下,所有工作都應該朝向復原實體機器進行。

下列動作可能會導致資料遺失。 請先進行檢查,再繼續遵循它們。

注意

除了針對特定分割區使用規定的方式,使用這些方法是「絕對」不安全的。

  • 使用 Repair-ServiceFabricPartition -PartitionIdSystem.Fabric.FabricClient.ClusterManagementClient.RecoverPartitionAsync(Guid partitionId) API。 此 API 可讓您指定分割區的識別碼,以移出仲裁遺失並移入潛在的資料遺失。
  • 如果您的叢集遇到導致服務進入仲裁遺失狀態的頻繁失敗,而且潛在的「遺失資料」是可接受的,則指定適當的 QuorumLossWaitDuration 值可以協助您的服務自動復原。 Service Fabric 會在執行復原之前等待提供的 QuorumLossWaitDuration 值 (預設值為 infinite)。 我們「不」建議這種方法,因為其可能會導致非預期的資料遺失。

Service Fabric 叢集的可用性

一般而言,Service Fabric 叢集是高度分散式環境,沒有任何單一失敗點。 任何一個節點的失敗都不會造成叢集的可用性或可靠性問題,主要是因為 Service Fabric 系統服務遵循先前提供的相同指導方針。 亦即,它們預設一律會搭配三個或更多個複本執行,而且無狀態的系統服務會在所有節點上執行。

基礎 Service Fabric 網路服務與失敗偵測層會完全分散。 大部分的系統服務可從叢集中的中繼資料重建,或了解如何從其他地方重新同步處理其狀態。 如果系統服務進入如先前所述的仲裁遺失情況,則叢集的可用性可能會受損。 在這些情況下,您可能無法在叢集上執行某些作業 (例如開始升級或部署新服務),但叢集本身仍正常運作。

執行中叢集上的服務將會在這些情況下保持執行中狀態,除非它們要求寫入至系統服務,以繼續運作。 例如,如果容錯移轉管理員處於仲裁遺失,則所有服務都會繼續執行。 但是任何失敗的服務都將無法自動重新啟動,因為這需要容錯移轉管理員的介入。

資料中心或 Azure 區域的失敗

在少數情況下,實體資料中心可能會由於斷電或網路連線中斷而暫時無法使用。 在這些情況下,在資料中心或 Azure 區域中的 Service Fabric 叢集和服務將無法使用。 不過,您的資料會保留下來

對於在 Azure 中執行的叢集,您可以在 Azure 狀態頁面上檢視中斷的更新。 實體資料中心部分或完全毀損的事件不太可能發生,但如此可能會失去其裝載的任何 Service Fabric 叢集或其中的服務。 此遺失包括在該資料中心或區域外部未備份的任何狀態。

有數種不同策略可讓服務在單一資料中心或區域的永久性或持續性失敗的情況下存活:

  • 在多個此類區域中,執行不同的 Service Fabric 叢集,並在這些環境之間使用容錯移轉和容錯回復的一些機制。 這種多叢集的主動/主動或主動/被動模型需要其他管理和作業碼。 此模型也需要協調來自資料中心或區域中服務的備份,以在某個服務失敗時,可以將這些備份用於其他資料中心或區域。

  • 執行跨越多個資料中心的單一 Service Fabric 叢集。 此策略的最低支援設定是三個資料中心。 如需詳細資訊,請參閱跨可用性區域部署 Service Fabric 叢集

    此模型需要額外的設定。 不過,優點是資料中心或區域的失敗會從災害轉換成一般失敗。 可藉由在單一區域內為叢集運作的機制來處理這些失敗。 容錯網域、升級網域,以及 Service Fabric 放置規則確保工作負載是分散的,以便容忍一般失敗。

    如需有助於在此類叢集中操作服務的原則詳細資訊,請參閱 Service Fabric 服務的放置原則

  • 使用獨立模型執行跨越多個區域的單一 Service Fabric 叢集。 建議的區域數目為 3 個。 如需獨立 Service Fabric 設定的詳細資料,請參閱建立獨立叢集

導致叢集失敗的隨機失敗

Service Fabric 具有「種子節點」的概念。 種子節點是維護基礎叢集可用性的節點。

種子節點有助於藉由建立與其他節點的租用,並在某些類型的失敗期間擔任仲裁者,來確保叢集保持正常運作。 如果隨機失敗移除叢集中的大多數種子節點,而且它們不會快速復原,您的叢集會自動關閉。 叢集接著會失敗。

在 Azure 中,Service Fabric 資源提供者會管理 Service Fabric 叢集設定。 根據預設,資源提供者會針對「主要節點類型」跨容錯網域和升級網域散發種子節點。 如果主要節點類型標示為銀級或金級持久性,則當您移除種子節點 (方法為在主要節點類型中進行規模調整,或手動將其移除) 時,叢集會嘗試從主要節點類型的可用容量中升階另一個非種子節點。 如果您的可用容量低於您的叢集可靠性層級針對主要節點類型所需的可用容量,此嘗試將會失敗。

在獨立 Service Fabric 叢集和 Azure 中,主要節點類型是指執行種子的節點類型。 當您定義主要節點類型時,Service Fabric 會自動利用藉由建立最多 9 個種子節點和每個系統服務 7 個複本所提供的節點數目。 如果在一組隨機失敗同時移除其中大多數的複本,系統服務會進入仲裁遺失。 如果大多數種子節點遺失,叢集將在不久後關閉。

下一步