怎麼構建健壯的分佈式系統?

原文鏈接:https://kislayverma.com/software-architecture/building-robust-distributed-systems/

作者:Kislay Verma

編輯:大白 

翻譯:大白

我之前在這個博客上寫過什麼是分佈式系統,以及它們如何以不得不處理更復雜的系統設計爲代價爲我們提供巨大的可擴展性。讓我們討論一下如何使分佈式系統對隨機故障具有彈性,隨着系統變大,這種隨機故障會變得越來越普遍。

系統理論告訴我們,系統中相互關聯的部分越多,發生大故障的可能性就越大。因此,要構建一個彈性系統,我們需要減少連接數量。如果無法做到這一點,我們需要實施 “臨時” 切斷與故障部分的連接的方法,以便錯誤不會級聯到其他部分。

每個組件都必須假設每個其他組件都會在某個時候發生故障,並決定當這些故障發生時它會做什麼。

最後,我們需要在系統中建立一些緩衝區——一些放鬆的方法,如果不消除對它的要求,以便有鬆弛來處理意外情況。

1

最小化組件間依賴

分佈式系統的組件相互通信以獲取數據或功能。在這兩種情況下,我們都可以通過將數據 / 功能推送到調用組件而不是遠程訪問來減少連接需求。

構建大規模分佈式系統迫使我們放棄標準軟件工程的許多 “最佳實踐”。要記住的關鍵是,當我們採用分佈式系統的複雜性來實現可擴展性時,我們還需要儘可能地控制 “分佈”。

1.1

重複數據

如果我們經常從另一個組件訪問一些數據,我們可以在我們的組件中複製它,而不必在運行時檢索它。這可以大大減少運行時依賴並幫助改善我們組件的延遲。

經常訪問但有一定規律性變化的數據可以通過定期緩存刷新來臨時緩存。更改頻率更低或從不更改的數據(例如客戶姓名)可以直接存儲在我們的組件中。如果 / 當這些數據發生變化時,我們可能需要做一些額外的工作,但是這種增加的小開銷通常是值得的,因爲它可以提高彈性。

1.2

非規範化數據

非規範化是在組件內發生的一種特殊形式的重複。如果我們使用關係數據存儲,我們可以通過在主實體中複製數據來降低查看多個實體的成本。本地化分散數據以獲得更好性能的原則也適用於此。

1.3

爲了減輕另一個組件的功能依賴性,我們可以將遠程組件打包爲庫並將其嵌入到我們的組件中。這並不總是可能的(它可能是用其他語言編寫的,或者太大而不能成爲一個庫)並且會帶來一系列問題(功能的變化需要跨多個組件進行庫升級),但是如果功能很關鍵並且經常被大規模訪問,這是打破組件間連接並使其成爲本地的可行方法。

2

隔離錯誤

錯誤隔離很重要,原因有兩個。一是個別錯誤在分佈式系統中更常見(許多移動部件的簡單功能)。另一個是,如果我們不能防止整個系統中的聯鎖錯誤,那麼我們首先就失去了構建複雜體的理由。

錯誤隔離的主要結構是 SLA。每個組件都聲明瞭一些質量參數,它將在執行功能時得到尊重。這些參數可以包括延遲、錯誤率、併發性等。

在此 SLA 之外,調用它的組件會假定它已失敗並需要自行採取適當的措施。如果組件本身檢測到它無法維護其 SLA,它可以先發制人地告訴其調用者暫停並稍後再來調用。

爲了保持整體系統健康,最好是快速失敗而不是在違反 SLA 的情況下成功。兩個組件(一個被喚起的和一個喚起的)都必須爲此設置機制。

2.1

保護調用者

超時:如果被調用的組件在其 SLA 內沒有響應,調用者必須超時(放棄)並改用一些回退機制(即使它拋出錯誤)來維護自己的 SLA 並防止一連串的 SLA 違規。

重試:由於網絡不可靠,分佈式系統中的許多錯誤只是隨機的。如果調用者自己的 SLA 允許,調用者可以重試該操作。重試的前提是操作的冪等性。即它不應該改變狀態或只做一次,即使它被調用了兩次。

斷路器:如果對組件的調用連續失敗,調用者可以通過 “打開電路” 切斷連接並停止調用一段時間。由於調用者已經有一些錯誤場景的備份行爲,這節省了調用者寶貴的資源,這些資源本來會被浪費掉。停止調用還可以減少被調用組件的負載,並給它一些恢復的喘息空間。

斷路器庫具有定期輪詢有問題的組件並在其性能似乎已恢復正常時重新啓動調用流程的機制。

2.2

保護被調用

隨機間隔:雖然重試可以減少錯誤,但在一個頻繁使用的組件中出現一個小的性能問題可能會導致其所有調用者一次重試。這種 “重試風暴” 會造成負載峯值並阻止該組件恢復。爲了防止這種情況,重試應該在它們之間有一個隨機的時間間隔,以便交錯加載。

背壓:如果一個組件檢測到自己承受過多的負載並且即將違反其 SLA,它可以搶先開始丟棄新請求,直到其性能得到控制。這比接受它知道它不能在 SLA 內提供服務或沒有完全崩潰風險的請求要好得多。

3

在系統中建立緩衝區

3.1

異步通信

消息總線之類的異步通信通道允許調用遠程組件,而無需非常嚴格的 SLA 依賴。通過讓被調用組件準備好而不是立即使用消息,系統對增加的工作負載的需求變得更加靈活。

3.2

彈性配置

可擴展性最終歸結爲充分利用可用硬件。但是,如果看到規模增長,讓系統緩口氣的一個簡單方法是分配更多硬件。雖然這僅在我們能夠承受的成本範圍內是可行的,但它爲我們提供了抵禦不可預測的負載變化的最後一道防線。

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