

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 了解可用性
<a name="understanding-availability"></a>

 可用性是我們可以量化測量恢復能力的主要方法之一。我們將可用性 *A* 定義為工作負載可供使用的時間百分比。這是其預期的「正常運行時間」（可用）與測量總時間（預期的「正常運行時間」加上預期的「停機時間」）的比率。

![\[方程的圖片。A = 正常運行時間/（正常運行時間 + 停機\]](http://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/images/availability.png)


 為了更好地理解此公式，我們將研究如何衡量正常運行時間和停機時間。首先，我們想知道工作負載將不會失敗多長時間。我們稱之為平*均故障間*隔時間 (MTBF)，即工作負載開始正常運作到下一次失敗之間的平均時間。然後，我們想知道失敗後恢復需要多長時間。

 我們稱此為*修復 (或復原) 的平均時間* (MTTR)，這是在修復失敗的子系統或返回服務時，工作負載無法使用的一段時間。MTTR 中的一個重要時間段是*平均偵測時*間 (MTTD)、發生故障與修復作業開始之間的時間長度。下圖說明所有這些度量如何相關。

![\[顯示 MTTD，MTTR 和 MTBF 之間的關係的圖表\]](http://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/images/availability-metrics.png)


 因此，我們可以表示可用性，*A*，使用 MTBF，工作負載啟動的時間和 MTTR，工作負載關閉的時間。

![\[方程的圖片。A = MTBF/(MTBF + 平方米)\]](http://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/images/equation2.png)


 而工作負載「下降」的概率（也就是說，不可用）是失敗的概率，*F*。

![\[方程的圖片。F = 1-一個\]](http://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/images/equation3.png)


[可靠性](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/reliability.html)是指工作負載能夠在要求時在指定的回應時間內完成正確事情的能力。這是什麼可用性措施。工作負載失敗的頻率較低 (MTBF 較長) 或修復時間較短 (縮短 MTTR)，可改善其可用性。

**規則 1**  
較少的故障頻率 (較長的 MTBF)、更短的故障偵測時間 (縮短 MTTD)，以及更短的修復時間 (縮短 MTTR) 是用來改善分散式系統可用性的三個因素。

**Topics**
+ [分散式系統可用](distributed-system-availability.md)
+ [可用性與相依性](availability-with-dependencies.md)
+ [備援的可用性](availability-with-redundancy.md)
+ [帽定理](cap-theorem.md)
+ [容錯和故障隔離](fault-tolerance-and-fault-isolation.md)

# 分散式系統可用
<a name="distributed-system-availability"></a>

 分佈式系統由軟件組件和硬件組件組成。某些軟體元件本身可能是另一個分散式系統。基礎硬體和軟體元件的可用性會影響工作負載產生的可用性。

 使用 MTBF 和 MTTR 的可用性的計算有其根源於硬件系統。但是，分散式系統失敗的原因與一個硬體完全不同。如果製造商可以持續計算硬體元件耗盡之前的平均時間，則相同的測試無法套用至分散式系統的軟體元件。硬體通常遵循故障率的「浴缸」曲線，而軟體則遵循由每個新版本引入的額外缺陷所產生的交錯曲線 (請參閱[軟體可靠性](https://users.ece.cmu.edu/~koopman/des_s99/sw_reliability))。

![\[顯示硬體和軟體故障率的圖表\]](http://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/images/failure-rates.png)


 此外，分散式系統中的軟體通常會以比硬體更高的速率變更。例如，標準磁性硬碟的平均年故障率 (AFR) 可能為 0.93%，在實際情況下，硬碟的使用壽命可能至少為 3-5 年，可能會延長 (請參閱 2020 年 [Backblaze](https://www.backblaze.com/b2/hard-drive-test-data.html) 硬碟資料與統計資料)。硬碟在該生命週期內不會發生重大變化，例如，在 3 到 5 年內，Amazon 可能會在其軟體系統上部署超過 450 至 7.5 億項變更。請參閱 [Amazon Builders' Library — 自動執行安全、免提](https://aws.amazon.com/about-aws/whats-new/2020/06/new-abl-article-automating-safe-hands-off-deployments/)部署。) 

 硬件也受到計劃過時的概念，即具有內置的壽命，在一段時間後需要更換。（見[偉大的燈泡陰謀](https://spectrum.ieee.org/tech-history/dawn-of-electronics/the-great-lightbulb-conspiracy)。） 從理論上講，軟件不受這種限制，它沒有磨損期，可以無限期地操作。

 所有這些都意味著用於生成 MTBF 和 MTTR 號碼的硬件的相同測試和預測模型不適用於軟件。自 1970 年代以來，已經有數百次嘗試構建模型來解決此問題，但它們通常分為兩類，即預測模型和估計建模。(請參閱[軟體可靠性型號清單](https://en.wikipedia.org/wiki/List_of_software_reliability_models)。) 

 因此，計算分佈式系統的前瞻性 MTBF 和 MTTR，從而具有前瞻性的可用性，將始終從某種類型的預測或預測衍生出來。它們可以通過預測建模，隨機模擬，歷史分析或嚴格的測試生成，但這些計算並不保證正常運行時間或停機時間。

 分散式系統過去失敗的原因可能永遠不會再次發生。future 失敗的原因很可能會有所不同，並且可能不知道。future 失敗所需的復原機制也可能與過去使用的復原機制不同，因此需要大幅不同的時間。

 此外，MTBF 和 MTTR 是平均值。從平均值到看到的實際值會有一些變化（標準差 σ，測量此變化）。因此，在實際生產使用中，工作負載可能會在故障和復原時間之間經歷較短或更長的時間 

 話雖如此，構成分佈式系統的軟件組件的可用性仍然很重要。軟體失敗的原因有許多 (在下一節中詳細討論)，並會影響工作負載的可用性。因此，對於高可用性的分散式系統而言，應該關注軟體元件的計算、測量和改善軟體元件的可用性等於硬體和外部軟體子系統。

**規則 2**  
 工作負載中軟體的可用性是工作負載整體可用性的重要因素，而且應該與其他元件相同。

 重要的是要注意，儘管 MTBF 和 MTTR 難以預測分散式系統，但它們仍然提供有關如何提高可用性的關鍵見解。降低故障頻率 (更高的 MTBF) 並減少故障發生後的復原時間 (降低 MTTR)，都會導致更高的實證可用性。

## 分散式系統中的故障類型
<a name="types-of-failures-in-distributed-systems"></a>

 在影響可用性的分佈式系統中通常有兩類錯誤，親切地命名為*博爾錯誤*和*海森*堡（見 [「與布魯斯·林賽的對話」，ACM 隊列第 2 卷，第 8-2004 年 11 月）。](http://queue.acm.org/detail.cfm?id=1036486)

 Bohrbug 是一個可重複的功能軟件問題。給定相同的輸入，該錯誤將始終產生相同的不正確輸出（如確定性的 Bohr 原子模型，它是固體且易於檢測的）。當工作負載進入生產環境時，這些類型的錯誤很少見。

 海森錯誤是一個暫時性的錯誤，這意味著它只發生在特定和不常見的情況下。這些條件通常與硬體 (例如暫時性裝置錯誤或硬體實作細節 (如暫存器大小)、編譯器最佳化和語言實作、限制條件 (例如暫時不在儲存空間) 或競爭條件 (例如，不使用信號量進行多執行緒作業)。

 Heiisenbugs 構成了生產中的大多數錯誤，並且很難找到，因為它們難以捉摸，並且在您嘗試觀察或調試它們時似乎會改變行為或消失。但是，如果您重新啟動程式，失敗的作業可能會成功，因為作業環境略有不同，從而消除了引入 Heiisenbug 的條件。

 因此，生產中的大多數故障都是暫時的，當重試操作時，不太可能再次失敗。為了保持彈性，分佈式系統必須對海森蟲具有容錯能力。我們將探討如何實現這一部[分增加分佈式系統 MTBF](increasing-mtbf.md#increasing-mtbf.title)。

# 可用性與相依性
<a name="availability-with-dependencies"></a>

 在上一節中，我們提到硬體、軟體和潛在的其他分散式系統都是您工作負載的元件。我們稱這些元件*相依性*為您的工作負載所依賴的項目來提供其功能。有一些*硬*性依賴關係，這是您的工作負載無法在沒有的情況下運行的東西，以及不可用性可能在一段時間內被忽視或容忍的*軟*相依性。硬式相依性會直接影響工作負載的可用性。

 我們可能想要嘗試計算工作負載的理論上最大可用性。這是所有相依性 (包括軟體本身) 的可用性產品 (*α* *n* 是單一子系統的可用性)，因為每個子系統都必須可以運作。

![\[方程的圖片。A = α 1 X α 2 X... X α n 下標資料 >\]](http://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/images/equation4.png)


 這些計算中使用的可用性數字通常與 SLA 或服務等級目標 (SLO) 等項目相關聯。SLA 定義了客戶將獲得的預期服務等級、測量服務的指標，以及如果未達到服務水平的補救或罰款（通常是金錢）。

 使用上面的公式，我們可以得出結論，純粹的數學上，工作負載不能超過其任何依賴關係。但實際上，我們通常看到的是情況並非如此。使用具有 99.99% 可用性 SLA 的兩個或三個相依性建置的工作負載本身仍可達到 99.99% 或更高的可用性。

 這是因為正如我們在上一節中概述的那樣，這些可用性數字是估計值。他們估計或預測故障發生的頻率以及修復的速度。它們不是停機時間的保證。相依性通常超過其規定的可用性 SLA 或 SLO。

 相依性也可能具有較高的內部可用性目標，這些目標是針對效能，而不是公開 SLA 中提供的數字。當未知或不可知的情況發生時，這提供了一定程度的降低風險，以滿足 SLA。

 最後，您的工作負載可能具有其 SLA 無法知道或不提供 SLA 或 SLO 的相依性。例如，全球網際網路路由是許多工作負載的共同依存性，但很難知道您的全球流量正在使用哪個網際網路服務提供者、它們是否具有 SLA，以及它們在提供商之間的一致性很難。

 這一切告訴我們的是，計算最大理論可用性只會產生粗略的數量級計算，但本身可能不準確或提供有意義的見解。數學確實告訴我們的是，您的工作負載所依賴的東西越少會降低整體失敗的可能性。少於一個乘以在一起的數字越少，結果越大。

**規則 3**  
 減少相依性可能會對可用性產生積極影響。

 數學還有助於通知依賴關係選擇過程。選取程序會影響您設計工作負載的方式、如何利用相依性中的備援來提高其可用性，以及您是否將這些相依性視為軟體或硬體。應仔細選擇可能對工作負載造成影響的依賴關係。下一條規則提供有關如何執行此操作的指導。

**規則 4**  
 一般而言，請選取可用性目標等於或大於工作負載目標的相依性。

# 備援的可用性
<a name="availability-with-redundancy"></a>

 當工作負載使用多個、獨立且備援的子系統時，與使用單一子系統相比，它可以達到更高層級的理論可用性。例如，考慮由兩個相同子系統組成的工作負載。它可以是完全可操作的，如果無論是子系統一個或子系統二是操作的。要使整個系統關閉，兩個子系統必須同時關閉。

 *如果一個子系統的故障概率為 1-*α*，那麼兩個冗餘子系統同時關閉的概率是每個子系統的故障概率的乘積，*F* =（1− *α*1）×（1− α）。* 2對於具有兩個備援子系統的工作負載，使用方程式 *(3)*，這會提供可用性定義為：

![\[三個方程式的圖片\]](http://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/images/equation5.png)


 因此，對於兩個可用性為 99％ 的子系統，其中一個失敗的可能性為 1％，並且它們都失敗的概率為（1− 99％）×（1− 99％）= .01％。這使得使用兩個備援子系統的可用性達 99.99%。

 **這可以概括來納入額外的冗餘備件，也是如此。**在方程式 *(5)* 中，我們只假設一個備用，但一個工作負載可能有兩個、三個或更多個備件，以便在多個子系統的同時損失中存活，而不會影響可用性。*如果工作負載有三個子系統，而兩個是備用系統，則三個子系統同時失敗的可能性為 (1− *α*) × (1− *α) × (1− α*) 或 (1− *α*) 3。*一般而言，只有當 **s** \$1 1 個子系統故障時，具有備用的工作負載才會失敗。

 *對於具有 *n* 個子系統和 *s* 備件的工作負載，*f* 是失敗模式的數量或 *s* \$1 1 個子系統可能會故障 n 的方式。*

 ***這實際上是二項式定理，即從一組 n 中選擇 *k* 個元素的組合數學，或者 *「***n** 選擇 k」。***在這種情況下，*k* 是 *s* \$1 1。

![\[四個方程式的圖片\]](http://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/images/equation6.png)


 然後，我們可以產生一個廣義的可用性近似值，其中包含了失敗模式和備用的數量。（要了解為什麼在近似值中這樣做，請參閱海萊曼等的附錄 2。 [打破可用性障礙](https://www.amazon.com/Breaking-Availability-Barrier-Survivable-Enterprise/dp/1410792331)。） 

![\[四個方程式的圖片\]](http://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/images/equation7.png)


 備用可套用至提供獨立失敗資源的任何相依性。不同 AZ 或 Amazon S3 儲存貯體中不同的 Amazon EC2 執行個體就AWS 區域是這個範例。使用備援可協助該相依性達到更高的整體可用性，以支援工作負載的可用性目標。

**規則五**  
 使用備用來增加工作負載中相依性的可用性。

 但是，備用是需要付出代價的。每個額外的備用成本與原始模塊相同，至少線性驅動成本。建置可以使用備援的工作負載也會增加其複雜性。它必須知道如何識別相依性失敗、將工作量從它轉移到健康狀態良好的資源，以及管理工作負載的整體容量。

 冗餘是一個優化問題。備用裝置太少，而且工作負載的故障頻率可能比預期的要高，備用裝置太多，而且工作負載執行的成本太高。有一個臨界值，即增加更多備件的成本將超過其實現認股權證的額外可用性。

 ***對於具有 99.5% 可用性的子系統，將我們的一般可用性與備用公式 *(7)* 搭配使用，工作負載的可用性為 *A* 1 − (1) (1−.995) 3 = 99.9999875% (每年停機時間約為 3.94 秒)，而在 10 個備用裝置中，我們會得到一*個* 1 − (1) (1−995) (1−9 ′) = 25.5 將是每年 1.26252 × 10 至 15 米，實際上是 0）。***在比較這兩個工作負載時，我們的備用成本增加了 5 倍，以實現每年減少 4 秒的停機時間。對於大部分的工作負載而言，成本的增加是不必要的，因為可用性的增加。下圖顯示了這種關係。

![\[顯示從增加的備用收益減少的圖表\]](http://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/images/effect-of-sparing.png)


 在三個備件及以後，結果是每年預期停機時間的一秒鐘的幾分之一，這意味著在這一點之後，您將到達收益遞減的區域。可能有衝動「只是添加更多」以實現更高水平的可用性，但實際上，成本效益消失非常快。當子系統本身至少具有 99% 的可用性時，使用三個以上的備用裝置並不能為幾乎所有工作負載帶來明顯的增益。

**規則第六條**  
 備用的成本效率有一個上限。利用所需的最少備用裝置來達到所需的可用性。

 選取正確的備援數目時，您應該考慮失敗單位。例如，讓我們檢查一個需要 10 個 EC2 執行個體來處理尖峰容量的工作負載，並將它們部署在單一 AZ 中。

 由於 AZ 設計為故障隔離界限，故障單位不僅是單一 EC2 執行個體，因為整個 AZ 值的 EC2 執行個體可能會一起失敗。在這種情況下，您需要[與另一個 AZ 新增冗餘](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/use-fault-isolation-to-protect-your-workload.html)，部署 10 個額外的 EC2 執行個體來處理 AZ 故障時的負載，總共 20 個 EC2 執行個體 (遵循靜態穩定性模式)。

 雖然這似乎是 10 個備用 EC2 實例，但它實際上只是一個備用 AZ，因此我們沒有超過收益遞減的點。不過，您可以更具成本效益，同時利用三個 AZ 並在每個 AZ 部署五個 EC2 執行個體來提高可用性。

 這為一個備用 AZ 提供總共 15 個 EC2 執行個體 (而兩個 AZ 具有 20 個執行個體)，仍然提供所需的 10 個執行個體總計，以在影響單一 AZ 的事件期間提供尖峰容量。因此，您應該在工作負載 (執行個體、儲存格、AZ 和區域) 使用的所有容錯隔離界限內建備容錯能力。

# 帽定理
<a name="cap-theorem"></a>

 我們可能會考慮可用性的另一種方式是與 CAP 定理有關。該定理指出，分佈式系統，一個由存儲數據的多個節點組成，不能同時提供以下三個保證中的兩個以上：
+  **C** 唯一性：無法保證一致性時，每個讀取請求都會收到最新的寫入或錯誤。
+  **有**效性：即使節點關閉或無法使用，每個請求都會收到非錯誤響應。
+  **P** 關節容差：即使節點之間遺失任意數量的訊息，系統仍會繼續運作。

（有關更多詳細信息，請參閱塞斯·吉爾伯特和南希·林奇，[http://dl.acm.org/citation.cfm?id=564601&CFID=609557487&CFTOKEN=15997970](http://dl.acm.org/citation.cfm?id=564601&CFID=609557487&CFTOKEN=15997970)*ACM SIGACT 新聞*，第 33 卷第 2 期（2002），第 51-59 頁。） 

 大多數分散式系統都必須容忍網路故障，因此必須允許網路磁碟分割。這表示當網路磁碟分割發生時，這些工作負載必須在一致性和可用性之間做出選擇。如果工作負載選擇可用性，則一律會傳回回應，但資料可能不一致。如果選擇一致性，那麼在網絡分區期間，它將返回一個錯誤，因為工作負載無法確定數據的一致性。

 對於其目標是提供更高層級的可用性的工作負載，他們可能會選擇可用性和分割區容許度 (AP)，以防止在網路磁碟分割期間傳回錯誤 (無法使用)。這導致需要更寬鬆的[一致性模型](https://en.wikipedia.org/wiki/Consistency_model)，例如最終一致性或單調一致性。

# 容錯和故障隔離
<a name="fault-tolerance-and-fault-isolation"></a>

 當我們考慮可用性時，這是兩個重要的概念。容錯能力是[承受子系統故障](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/design-your-workload-to-withstand-component-failures.html)並維持可用性的能力（在已建立的 SLA 內做正確的事情）。若要實作容錯，工作負載會使用備用 (或備援) 子系統。當冗餘集合中的其中一個子系統發生故障時，另一個子系統會取得其工作，通常幾乎無縫。在這種情況下，備用零件是真正的備用容量；它們可以承擔故障子系統 100% 的工作。使用真正的備援裝置時，需要多個子系統故障，才能對工作負載產生不利影響。

 故障隔離可最大限度地減少發生故障時的影響範圍。這通常是通過模塊化實現的。工作負載會分解成小型子系統，這些子系統會獨立故障，而且可以單獨修復。模塊的故障[不會傳播到模塊之外](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/design-interactions-in-a-distributed-system-to-mitigate-or-withstand-failures.html)。這個想法橫跨工作負載中的不同功能，以及橫向跨越提供相同功能的多個子系統。這些模組充當錯誤容器，可限制事件期間的影響範圍。

 控制平面、資料平面和靜態穩定性的架構模式直接支援實作容錯和容錯隔離。Amazon Builder Library 文章[使用可用區域的靜態穩定性](https://aws.amazon.com/builders-library/static-stability-using-availability-zones)為這些術語提供了良好的定義，以及它們如何適用於建置彈性、高可用性的工作負載。本白皮書在 [[設計上的高可用性分散式系統] 一節中使用了這些模式AWS，](designing-highly-available-distributed-systems-on-aws.md#designing-highly-available-distributed-systems-on-aws.title)我們也在此總結它們的定義。
+  **控制平面** — 進行變更所涉及的工作負載部分：新增資源、刪除資源、修改資源，以及將這些變更傳播到需要的位置。控制平面通常比資料平面更複雜，而且具有更多的移動零件，因此在統計學上更容易發生故障並具有較低的可用性。
+  **資料平面** — 提供 day-to-day 業務功能的工作負載部分。數據平面往往比控制面更簡單，並且以更高的體積運行，從而導致更高的可用性。
+  **靜態穩定性** — 儘管相依性受損，工作負載仍能繼續正確操作的能力。實現的一種方法是從數據平面中刪除控制平面依賴關係。另一種方法是鬆散耦合工作負載相依性。也許工作負載沒有看到任何更新的信息（例如新事物，刪除的東西或修改的東西），它的依賴項應該已經交付。但是，在依賴關係受損之前它所做的一切都繼續起作用。

 當我們考慮工作負載的損害時，我們可以考慮兩種高層次的方法進行恢復。第一種方法是在損害發生後對該損害做出反應，也許使用AWS Auto Scaling來添加新的容量。第二種方法是在這些損壞發生之前做好準備，也許是通過過度佈建工作負載的基礎結構，以便它可以繼續正確運行，而不需要額外的資源。

 靜態穩定的系統使用後一種方法。它預先佈建了故障期間可用的備用容量。此方法可避免在工作負載復原路徑中建立控制平面的相依性，以便佈建新容量以從故障中復原。此外，為各種資源佈建新容量需要時間。在等待新容量時，您的工作負載可能會因現有需求而超載，並經歷進一步降級的情況，進而導致「中斷」或完全可用性損失。但是，您也應該考慮將預先佈建的容量用於可用性目標的成本影響。

 靜態穩定性為高可用性工作負載提供接下來的兩個規則。

**規則第 7 條**  
 請勿依賴資料平面中的控制平面，尤其是在復原期間。

**規則第 8 條**  
 鬆散地耦合相依性，因此您的工作負載可以在可能的情況下正確運作，儘管依賴 