構建分布式系統的五個挑戰
通過接受挑戰并將其納入您的設計中,您可以獲得分布式系統的真正好處。讓我們一一看看這些挑戰。
如今,分布式系統風靡一時。
每當我訪問 Internet 上的技術出版物時,我通常會發現一大堆關于分布式系統的好處的帖子。每個人似乎都對分布式系統的一般概念及其帶來的表面優勢著迷。
雖然創建可以幫助人們學習的信息內容沒有壞處,但我發現很多時候分布式應用程序被設計為易于構建的東西。
然而,現實卻大不相同。
構建和運行分布式系統很困難。否則不要讓別人告訴你。
創建分布式系統的任務充滿挑戰。具有諷刺意味的是,許多挑戰源于使這些系統首先具有吸引力的好處。在嘗試構建分布式系統時,您不應忽視這些挑戰。如果你這樣做,你最終會陷入麻煩的世界。
但是,如果您接受這些挑戰并將它們納入您的設計中,您就可以獲得分布式系統的真正好處。讓我們一一看看這些挑戰。
溝通
分布式系統是分布式的。
多個節點。可能是地理上分開的。
沒有其各個節點之間的通信,任何分布式系統都無法運行。
即使是在 Web 瀏覽器中瀏覽網站這一看似簡單的任務,也需要不同進程之間進行大量通信。
當我們訪問一個 URL 時,我們的瀏覽器會聯系 DNS 來解析該 URL 的服務器地址。一旦獲得地址,它就會通過網絡向服務器發送 HTTP 請求。服務器處理請求并發回響應。
系統設計者應該問幾個關于通信方面的重要問題:
- 請求和響應消息是如何通過網絡表示的?
- 在網絡中斷的情況下會發生什么?
- 我們如何保證安全免受窺探?
我們可以通過退回到 TCP 和 HTTPS 等抽象來應對其中的許多通信挑戰。
但是,抽象可能會泄漏。例如,TCP 試圖提供底層不可靠網絡的完整抽象。但如果網絡電纜被切斷或過載,TCP 將無能為力。當這種情況發生時,挑戰就落到了系統設計者身上。
協調
想象一下,有兩位將軍和他們各自的軍隊。他們需要相互配合才能同時進攻一座城市。只有同時進攻,才能攻下城池。為此,他們需要就攻擊時間達成一致。
由于軍隊在地理上是分開的,將軍們只能通過派遣使者來進行交流。不幸的是,信使必須穿過敵人的領土并可能被俘虜。
兩位將軍怎么能就進攻時間達成一致呢?
他們中的一個可以通過發送信使并等待響應來向另一個建議時間。但是,如果沒有響應怎么辦?會不會是信使被抓了?信使會不會受傷并且需要比預期更長的時間?將軍應該再派一個使者嗎?
這個問題不是微不足道的。
無論派出多少使者,兩位將軍都不能確定對方軍隊會在正確的時間攻城。派遣更多的使者可以增加協調成功的機會,但機會永遠不會達到 100%。
在分布式系統的上下文中,這個問題被稱為二一般問題。將軍就像分布式系統中的節點。為了使系統工作,節點應該相互協調。但是,節點隨時可能因故障而失效。
在開始時,每個開發人員都覺得他們將構建一個無故障的系統。我以前也是這么想的。當然,這是一種天真的追求,注定要失敗。您無法構建一個完全沒有錯誤的系統。分布式系統越大,出現故障的概率就越高。盡管存在一個或多個故障,容錯系統仍可以繼續運行。訣竅是使系統中的節點在出現故障時相互協調。
可擴展性
在構建分布式系統時,可伸縮性通常會引起系統設計人員的最大關注。
在基本層面上,可伸縮性是衡量系統性能隨負載增加的指標。
但是我們如何衡量分布式系統的性能和負載呢?
- 對于性能,我們可以使用兩個優秀的參數:吞吐量和響應時間。吞吐量表示每秒處理的操作數。響應時間是客戶端請求和響應之間經過的總時間。
- 系統負載的測量更具體到系統用例。例如,系統負載可以通過并發用戶數、通信鏈路或寫入與讀取的比率來衡量。
性能和負載本質上是相互關聯的。隨著負載的增加,最終會達到系統的容量。容量可能取決于系統的物理限制,例如:
- 節點的內存大小或時鐘周期
- 網絡鏈路的帶寬和延遲
當負載達到容量時,系統的性能要么停滯不前,要么惡化。
如果系統上的負載繼續增長超過容量,它最終會達到大多數操作失敗或超時的程度。吞吐量下降,響應時間猛增。此時,系統不再具有可擴展性。請參見下圖,該圖顯示了這種情況。
我們如何使系統具有可擴展性?
如果負載超出容量是導致性能下降的原因,我們可以通過增加容量來使系統具有可擴展性。增加容量的一種快速簡便的方法是購買具有更好性能指標的更昂貴的硬件。這種方法稱為放大。
盡管在紙面上聽起來不錯,但這種方法遲早會碰壁。
更可持續的方法是通過向系統添加更多機器來進行擴展。
如果您有興趣,我還對分布式系統中的可擴展性有更詳細的了解。
彈性
故障在分布式系統中很常見。有幾個原因:
- 首先,向外擴展會增加失敗的可能性。由于系統中的每個組件都有發生故障的內在概率,因此添加更多部件會增加總體故障概率。
- 其次,更多的組件意味著更多的操作。這增加了系統中故障的絕對數量。
- 最后,失敗不是獨立的。一個組件的故障會增加其他組件發生故障的可能性。
當系統大規模運行時,任何可能發生的故障最終都會發生。理想的分布式系統必須接受故障并以彈性方式運行。當一個系統即使在發生故障時也能繼續工作時,就被認為是有彈性的。
我們可以使用多種技術(例如冗余和自我修復機制)來提高系統的彈性。然而,這不是零和游戲。沒有分布式系統可以 100% 有彈性。在某些時候,故障會削弱系統的可用性。
可用性是一個重要指標。它是應用程序可以為請求提供服務的時間除以測量的持續時間。
組織通常使用 9 的概念以百分比形式推銷其系統的可用性。三個九 (99.9%) 通常被認為對大量系統來說是可以接受的。任何超過四個九 (99.99%) 的東西都是高可用的。關鍵任務系統可能需要更多的 9。
這是一個方便的圖表,它展示了實際停機時間的可用性百分比。
操作
在所有其他挑戰中,操作分布式系統可能是最困難的。但我也看到了這一領域發生的最重要的創新。就像任何其他軟件系統一樣,分布式系統也需要經歷開發、測試、部署和運行的軟件開發生命周期。
然而,過去由兩個獨立的團隊或部門來開發和操作軟件的日子已經一去不復返了。分布式系統的復雜性催生了DevOps。現在,設計和開發系統的同一個團隊有望在生產環境中運行它。這給開發團隊帶來了一些他們之前忽略的困難。
- 需要以安全的方式不斷推出新的部署。
- 系統需要是可觀察的。
- 當服務水平目標有被破壞的風險時,需要發出警報。
這種變化也有積極的一面。對于開發人員來說,沒有比提供隨叫隨到的支持更好的方法來找出系統的不足之處了。只要確保為破壞你的周末而得到適當的報酬!
結論
構建分布式系統并非易事。它充滿了圍繞通信、協調、可擴展性、彈性和 運營領域的多重挑戰。但解決這些挑戰是有益的。當分布式系統按計劃工作時,它會創造出一種特殊的組件舞蹈,令人賞心悅目。