譯者 | 劉汪洋
審校 | 重樓
分布式系統的復雜性是工程師和開發人員面臨的重大挑戰。隨著系統的迭代,復雜性往往會增加,因此提前做好準備至關重要。接下來,我們將討論你可能遇到的復雜性類型,以及在工作中應對這些復雜性的有效策略。
在開發過程中,分布式系統是由多個相互連接并協同完成任務的計算機組成的網絡。每臺計算機或節點都有自己的本地內存和處理器,并運行各自的進程。然而,它們通過一個公共網絡進行協調和集中管理。分布式系統具有高度的可靠性;單個組件的故障不會破壞整個網絡的運作。
在集中式計算系統中,通常由一臺具有單個處理器和內存的計算機負責解決問題。雖然集中式系統也包含多個節點,但所有節點都訪問一個中央節點,這可能導致網絡擁塞和速度減慢。集中式系統的一個顯著缺點是存在單點故障的風險。
復雜性可以從不同的角度進行定義,這里有兩個主要定義值得注意。
在系統理論中,復雜性描述了系統中不同獨立部分之間的相互作用和通信方式:它們如何相互定義、相互依賴,以及這些依賴關系的數量和性質。
從軟件和技術的角度來看,復雜性指的是軟件架構的細節,例如組件的數量和相互關系的復雜性。
單體架構是集中式系統的一個典型代表。它通常表現為一個可部署和可執行的整體。例如,這種架構的組件可能包括一個用戶界面以及位于同一位置的多個模塊。
盡管單體架構是傳統的軟件構建方式,但它存在一些顯著的缺點:
微服務架構是一種面向服務架構的變體,旨在將系統拆分為一組松散耦合的服務。例如,公司、賬戶、客戶和用戶界面這些功能模塊,會作為獨立進程部署在多個節點上。
雖然每個服務都有其獨立的數據庫,但這種做法有時可能不理想,甚至被視為反模式。
微服務架構具有以下優勢:
任何系統都具有以下三個主要質量屬性:
“任何可能出錯的事情都會出錯,并且會在最糟糕的時候?!?——墨菲定律
網絡的不可靠性有多種原因,例如:
最簡單的解決方案是在調用方設置超時邏輯。例如,如果調用方在一段時間內沒有收到響應,就會拋出錯誤并向用戶顯示錯誤信息。
在大規模系統中,我們不能因為每個網絡問題都拋出異常,從而讓用戶不滿或延遲系統的執行。因此,如果響應出現了問題,只需重試即可。但如果請求已被服務器處理,只是響應丟失了呢?在這種情況下,重試可能會導致嚴重后果,如多次下單、支付或交易等。
為避免這種情況,可以使用冪等性技術。
冪等性指多次執行相同操作的效果與執行一次相同。為了實現精準的“一次性語義”,可以在請求中附加冪等鍵。重試相同請求時,如果附帶相同的冪等鍵,服務器會驗證該鍵對應的請求是否已被處理,并直接返回之前的響應。這樣,無論重試多少次,相同的鍵都不會對系統行為產生不良影響。
斷路器是另一種有效的模式,尤其適用于防止服務器過載和完全崩潰的情況。
斷路器充當代理,以防止調用系統進入維護狀態,可能會失敗,或者正在嚴重失敗。失敗的原因可能有很多:內存泄漏、代碼錯誤或外部依賴故障。在這種情況下,快速失敗比冒著級聯故障的風險要好得多。
并發是分布式系統中最復雜的挑戰之一。并發意味著多個計算同時進行。
那么,當試圖同時從不同操作更新賬戶余額時會發生什么?如果沒有防護機制,很可能會發生競爭條件,導致寫入丟失和數據不一致。在這個例子中,兩個操作試圖同時更新賬戶余額。由于它們是并行運行的,最后一個完成的操作將獲勝,從而導致嚴重問題。為避免這種問題,可以采用多種技術。
ACID 是原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability)的縮寫。所有流行的 SQL 數據庫都實現了這些屬性。
快照隔離的關鍵思想是數據庫會跟蹤已記錄的版本,并且不會提交那些在當前事務之外已被修改的事務。
大多數 NoSQL 數據庫選擇 BASE(基本可用、軟狀態、最終一致性)時不提供 ACID 屬性,但廣泛使用比較并設置(Compare and Set, CAS)。這種操作旨在避免更新丟失,僅在值自上次讀取后未更改時才允許更新。如果當前值與之前讀取的值不匹配,更新不會生效,必須重試讀取-修改-寫入循環。
例如,Cassandra 提供輕量級事務,允許使用各種 IF、IF NOT EXISTS 和 IF EXISTS 條件來避免并發問題。
另一種解決方案是租約機制。例如,當需要獨占更新某個資源時,租約機制要求首先為資源獲取一個帶有到期時間的租約,然后進行更新,最后歸還租約。
在發生故障的情況下,租約會自動到期,從而允許另一個線程訪問資源。盡管這種技術非常有用,但存在進程暫停和時鐘不同步的風險,這可能導致并行資源訪問的問題。
雙寫問題是在分布式系統中需要同步多個數據源或數據庫時的一個常見挑戰。例如,假設一個場景需要將新數據存儲到數據庫并發送消息到 Kafka。由于這兩個操作不是原子的,因此在發布新消息時可能會失敗。
如果在發送消息時嘗試進行事務操作,情況會更加復雜。如果事務未能提交,外部系統可能已經收到實際上并未發生的更改信息。
一種潛在的解決方案是實施事務性發件箱。這種方法是在與操作本身相同的事務中,將事件存儲在 "OutboxEvents" 表中。由于過程的原子性,如果事務失敗,將不會存儲任何數據。
另一個必要組件是 Relay,它定期輪詢 OutboxEvents 表并將消息發送到目標。這種方法可以實現至少一次交付保證。由于網絡不可靠,所有消費者都必須具有冪等性,因此這并不是一個問題。
構建自定義事務性外發箱的另一種替代方案是利用數據庫事務日志和自定義連接器直接從日志中讀取并將更改發送到目標。
這種方法有其自身的優點和缺點。例如,它需要與數據庫解決方案耦合,但允許在應用程序中編寫更少的代碼。
時間跟蹤是任何軟件或基礎設施的基本方面,因為它能夠執行超時、到期和收集指標。然而,在分布式系統中,時鐘的可靠性是一個重大挑戰,因為時間的準確性取決于各個計算機的性能,而這些計算機的時鐘可能快于或慢于其他時鐘。
計算機使用的主要有兩種類型的時鐘:日歷時鐘和單調時鐘。日歷時鐘根據特定日歷返回日期和時間,通常與網絡時間協議(NTP)同步。然而,延遲和網絡問題可能會影響同步過程,導致時鐘不同步。單調時鐘則是連續推進的,適合測量持續時間。
然而,單調遞增值是每臺計算機獨有的,限制了它們在多服務器之間日期和時間比較中的使用。實現高度準確的時鐘同步是一項挑戰性任務。在大多數情況下,這種解決方案的必要性并不明顯。然而,在需要遵守法規的情況下,可以使用精確時間協議(PTP),但這將需要大量投入。
CAP 定理指出,任何分布式數據存儲系統只能同時滿足以下三個保證中的兩個:一致性(Consistency)、可用性(Availability)和分區容錯性(Partition Tolerance)。由于網絡的不可靠性是一個無法顯著改變的因素,在網絡分區的情況下,必須在可用性和一致性之間進行選擇。
考慮以下場景:兩個客戶端分別從不同的節點讀取數據,一個從主節點讀取,另一個從從節點讀取。復制配置在 leader 更改后更新 follower 節點。但是,如果由于某種原因 leader 停止響應會發生什么?
這可能是由于崩潰、網絡分區或其他問題。在高可用系統中,必須指定一個新的 leader ,但如何選擇現有的 follower 節點呢?為了解決這個問題,必須采用一種分布式共識算法。然而,在深入探討這種算法之前,有必要全面了解各種類型的一致性。
一致性保證主要分為兩類:
回到 leader 崩潰的問題,需要選舉一個新的 leader 。這個問題乍看之下很簡單,但實際上在選擇合適的方法時需要考慮許多條件和權衡。
根據 Raft 協議,如果 follower 在指定時間內沒有收到來自 leader 的數據或心跳信號,則會開始新的 leader 選舉過程。每個復制單元(單體寫節點或多個分片)都與一組 Raft 日志和操作系統進程相關聯,這些進程維護日志并將更改從 leader 復制到 follower 節點。
Raft 協議保證 follower 節點按照 leader 生成的順序接收日志記錄。當一半的 follower 節點確認收到提交記錄并將其寫入 Raft 日志時,用戶事務便在 leader 上提交。
一種可能的有效且簡單的策略是由剛剛保存新數據的用戶從 leader 讀取,以避免復制延遲。
從單體架構到微服務架構,每種方法都有其優點和挑戰。雖然單體架構提供了簡潔性,但它們通常在可擴展性和可維護性方面表現不佳,這推動開發人員向更加模塊化和可擴展的微服務架構發展。
討論的核心是復雜性的管理,這種復雜性以各種形式表現出來,從網絡不可靠到并發問題再到雙寫問題。諸如超時、重試、冪等性和斷路器等策略為減輕網絡不可靠帶來的風險提供了有效的工具,而快照隔離、比較并設置以及租約等技術則解決了并發和丟失寫入的挑戰。
此外,不可靠時鐘的關鍵問題強調了在分布式系統中準確時間同步的重要性,從 NTP 同步到精確時間協議(PTP),都提供了相應的解決方案。此外,CAP 定理提醒我們在可用性和一致性之間固有的權衡,迫使我們深入了解諸如 Raft 之類的分布式共識算法。
總之,掌握分布式系統中的復雜性需要多方面的方法,需要理論與實踐相結合。通過采用這些策略并不斷適應不斷變化的分布式計算領域,工程師和開發人員可以應對這些復雜性挑戰,確保其系統在面對不斷變化的挑戰時的可靠性、可擴展性和可維護性。
劉汪洋,51CTO社區編輯,昵稱:明明如月,一個擁有 5 年開發經驗的某大廠高級 Java 工程師,擁有多個主流技術博客平臺博客專家稱號。
原文標題:Distributed Systems: Common Pitfalls and Complexity,作者:Aleksei Popov
本文鏈接:http://www.tebozhan.com/showinfo-26-92594-0.html分布式系統:常見陷阱和應對復雜性的有效策略
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com