聊聊流言協議(Gossip)

什麼是流言協議?

在分佈式系統中,以下兩個是典型的問題:

  • 維護系統狀態(節點的活躍性)
  • 節點間的通信

解決這些問題的解決方案之一如下:

  • 集中式狀態管理服務
  • 對等狀態管理服務

集中式狀態管理服務

像 Apache Zookeeper 這樣的集中式狀態管理服務可以被配置爲服務發現,以跟蹤系統中每個節點的狀態。儘管這種方法提供了強大的一致性保證,但主要缺點是狀態管理服務成爲單點故障,並且對於大型分佈式系統也會遇到可擴展性問題。

對等狀態管理服務

對等狀態管理方法傾向於高可用性和最終一致性。可以使用流言協議算法(Gossip Protocol)來實現具有高可擴展性和改進的彈性的對等狀態管理服務。
流言協議也被稱爲流行病協議,因爲消息的傳輸類似於流行病的傳播方式。流言協議中的通信概念類似於謠言在公司員工之間的傳播,或者是信息在社交媒體網站上的傳播。

廣播協議

在分佈式系統中,流行的消息廣播技術包括:

  • 點對點廣播
  • 可靠廣播
  • 流言協議

點對點廣播

在點對點廣播中,生產者直接向消費者發送消息。生產者上的重試機制和消費者上的去重機制使點對點廣播可靠。當生產者和消費者同時失敗時,消息會丟失。

可靠廣播

每個節點通過可靠的網絡鏈接將消息重新廣播給每個其他節點。這種方法提供了改進的容錯性,因爲即使生產者和消費者同時失敗,消息也不會丟失。剩餘節點將重新廣播消息。可靠廣播的注意事項包括:

  • 由於爲 n 個節點廣播 O(n²) 條消息,導致顯著的網絡帶寬使用
  • 發送節點可能因O(n)線性廣播而成爲瓶頸
  • 每個節點存儲系統中所有節點的列表,導致存儲成本增加

流言協議

流言協議是一種去中心化的對等通信技術,用於在龐大的分佈式系統中傳輸消息。流言協議的關鍵概念是每個節點定期向其他隨機節點的子集發送消息。整個系統最終將以很高的概率接收到特定消息。概括來說就是,流言協議是一種通過有限的局部交互建立全局映射的技術。

流言協議建立在健壯、可擴展且最終一致的算法之上。流言協議通常用於維護分佈式系統中的節點成員列表、達成共識和故障檢測。此外,還可以在流言消息上附帶應用程序級數據等附加信息。

流言協議是可靠的,因爲節點故障可以通過另一個節點重新傳輸消息來克服。可以使用流言協議實現先進先出(FIFO)廣播、因果廣播和完全順序廣播。

可以調整流言協議參數,如週期和扇出,以提高流言協議的概率保證。

流言協議的以下特性使其成爲大規模分佈式系統中通信協議的最佳選擇:

  • 限制每個節點傳輸的消息數量
  • 限制帶寬消耗,防止應用程序性能下降
  • 容忍網絡和節點故障

只有當執行的操作是可交換的,並且不需要序列化時,流言協議才能用於保持節點一致性。墓碑是一種特殊條目,用於使具有匹配鍵的數據條目無效,而不是實際刪除數據。流言協議使用墓碑從節點中刪除數據。

流言協議類型

在選擇特定用例的流言協議類型時,必須考慮流言協議傳播消息所需的時間和在傳播消息時產生的網絡流量。流言協議可以大致分類爲以下類型:

  • 反熵增模型
  • 謠言傳播模型
  • 聚合模型

反熵增流言協議

反熵增算法旨在減少如數據庫等有狀態服務的副本之間的熵。比較複製的數據,並修補副本之間的差異。在每個流言輪次中,擁有最新消息的節點將其與其他節點共享。

反熵增模型通常會傳輸整個數據集,導致不必要的帶寬使用。可以使用諸如校驗和、最近更新列表和 Merkle 樹等技術來識別節點之間的差異,以避免傳輸整個數據集並減少網絡帶寬使用。反熵增流言協議將發送無限數量的消息,沒有終止。

謠言傳播流言協議

謠言傳播協議也被稱爲傳播協議。謠言傳播週期比反熵增週期發生得更頻繁,並以最壞情況負載淹沒網絡。謠言傳播模型使用更少的資源,如網絡帶寬,因爲只有最新的更新被傳輸到節點之間。

消息在幾輪通信後將被標記爲已刪除,以限制消息的數量。通常,消息有很高的概率到達所有節點。

聚合流言協議

聚合流言協議通過採樣每個節點的信息並結合值來計算系統範圍的聚合值。

通過流言協議傳播消息的策略

流言協議是構建高可用服務的最佳框架。通過流言協議傳播消息的策略應根據服務要求和可用的網絡條件進行選擇。在帶寬、延遲和可靠性方面,每種傳播消息的策略都有權衡。適用於反熵增和謠言傳播模型的傳播消息的不同策略如下:

  • 推模型
  • 拉模型
  • 推拉結合模型

推模型

當只有少數更新消息時,推模型是有效的,因爲流量開銷。在推模型中,擁有最新消息的節點將消息發送給其他節點的隨機子集。

拉模型

在拉模型中,每個節點將主動輪詢節點的隨機子集,以獲取任何更新消息。當有許多更新消息時,這種方法是有效的,因爲很有可能找到具有最新更新消息的節點。

推拉結合模型

推拉結合模型是快速可靠傳播更新消息的最佳選擇。節點可以推送新更新消息,也可以輪詢新更新消息。推方法在初始階段是有效的,因爲只有少數節點具有更新消息。拉方法在最後階段是有效的,當時有許多節點具有許多更新消息。

流言協議性能

從特定節點接收消息的節點數稱爲扇出。將消息傳播到整個集羣所需的流言輪數稱爲週期

將消息傳播到集羣所需的週期數 = O(log n),其中 n = 節點總數

例如,將消息傳播到 25,000 個節點大約需要 15 輪流言。可以將流言間隔設置爲低至 10 ms,以在大約 3 s 內將消息傳播到大型數據中心。流言協議中的信息傳播應自動老化,以減少不必要的負載。可以使用以下指標來衡量流言協議實現的性能:

  • 殘留:尚未收到消息的剩餘節點數量應最小化
  • 流量:節點之間發送的平均消息數應最小化
  • 收斂:每個節點應儘快收到消息
  • 時間平均:將消息發送給每個節點所需的平均時間應低
  • 時間最後:最後一個節點收到消息所需的時間應低

案例研究表明,具有 128 個節點的系統在運行流言協議時消耗的 CPU 不到 2 %,帶寬不到 60 KBps。

流言協議屬性

沒有正式的方法來定義流言協議。一般來說,流言協議應該滿足以下屬性:

  • 節點選擇必須是隨機的,以執行扇出
  • 每個節點只有本地信息可用,並且節點不瞭解集羣的狀態
  • 節點之間的通信涉及定期的、成對的、進程間交互
  • 每個流言輪次的傳輸容量有界
  • 每個節點部署相同的流言協議
  • 假設節點之間存在不可靠的網絡路徑
  • 節點交互頻率低
  • 節點交互導致狀態交換

流言算法

流言算法的流程如下:

  1. 每個節點維護一個節點子集及其元數據的列表
  2. 定期向隨機活動對等節點的端點流言
  3. 每個節點檢查接收到的流言消息,將最高版本號合併到本地數據集中

當特定節點參與流言交換時,節點的心跳計數器會增加。當心跳計數器持續增加時,節點被標記爲健康。另一方面,當心跳計數器由於網絡分區或節點故障而在很長一段時間內沒有變化時,節點被認爲不健康。其中,流言協議中對等節點選擇的不同標準如下:

  • 使用編程語言提供的庫,如使用 java.util.random
  • 與聯繫最少的節點進行交互
  • 強制執行網絡拓撲感知交互

流言協議實現

流言協議通過用戶數據報協議(UDP)或傳輸控制協議(TCP)傳輸消息,具有可配置但固定的扇出和間隔。對等採樣服務由流言協議用於識別流言消息交換的對等節點。對等採樣服務使用隨機算法選擇對等節點。對等採樣服務的接口一般會提供以下功能接口:

  • /gossip/init:在啓動時返回特定節點已知的節點列表
  • /gossip/get-peer:返回獨立對等節點的地址(IP 地址和端口號)

對等採樣服務執行的工作流程如下:

  1. 使用系統的部分視圖(節點子集的列表)初始化每個節點
  2. 在流言交換上將節點的視圖與對等節點的視圖合併

換句話說,每個節點維護一個小的本地成員表,具有系統的部分視圖,並通過流言消息定期刷新表。流言協議可以利用概率分佈選擇對等節點,以減少向同一節點傳輸重複消息。

應用程序狀態可以通過流言協議作爲鍵值對傳輸。當節點對同一鍵執行多個更改時,必須傳輸最新值。流言協議提供的 API 來協調應用程序狀態交換如下:

  • /gossip/on-join
  • /gossip/on-alive
  • /gossip/on-dead
  • /gossip/on-change

種子節點是基於靜態配置的完全功能節點。系統中的每個節點都必須知道種子節點。流言系統與種子節點交互,以防止邏輯分區。當節點接收到包含對等節點元數據的流言消息時,以下是由流言協議執行的詳細流程:

  1. 比較傳入的流言消息,以識別本地節點數據集中缺失的值
  2. 比較傳入的流言消息,以識別對等節點數據集缺失的值
  3. 當節點已經包含傳入流言消息中存在的值時,選擇更高版本值
  4. 在本地節點的數據集中附加缺失的值
  5. 在響應中返回對等節點數據集中缺失的值
  6. 使用收到的響應更新對等節點的數據集

通常,在節點啓動時,通過流言協議傳輸整個節點元數據。每個節點可以通過維護一個內存中的版本號,通過流言協議只發送節點元數據的增量更新。

生成時鐘是一個單調遞增的數字,表示服務器的生成。每當節點重新啓動時,生成時鐘就會增加。版本號保證了應用程序狀態的排序和版本控制。版本號只能增加。生成時鐘可以與版本號一起使用,以在節點重新啓動時正確檢測節點元數據的更改。

流言定時器是流言協議的一個組件,將確保每個節點最終包含有關對等節點的關鍵元數據,包括位於網絡分區後面的節點。每個節點都包含與之關聯的心跳。心跳狀態由生成和版本號組成。應用程序狀態由表示節點狀態的鍵值對和版本號組成。

發起流言交換的節點發送一個流言摘要同步消息,該消息包含流言摘要的列表。流言摘要包含端點地址、生成編號和版本號。流言摘要確認消息包含流言摘要列表和端點狀態列表。

流言協議應用場景

流言協議在許多最終一致性受到青睞的應用程序中使用。流言協議的流行應用程序如下:

  • 數據庫複製
  • 信息傳播
  • 維護集羣成員資格
  • 故障檢測
  • 生成聚合(計算平均值、最大值、總和)
  • 生成覆蓋網絡
  • 領導者選舉

流言協議可以以很高的概率在分佈式系統中檢測節點故障。節點故障的檢測可以節省 CPU、帶寬和隊列空間等資源。在分佈式系統中,當單個客戶端無法與特定節點交互時,不能斷言節點故障,因爲可能會發生網絡分區或客戶端故障。當幾個節點(客戶端)通過流言協議確認特定節點的活動性時,可以確定特定節點的故障。

流言協議對於數據交換和指揮控制比通過 TCP 連接更可靠。流言協議允許將關於節點和子系統屬性的通信從應用程序邏輯中抽象出來。可以將諸如平均負載和空閒內存之類的節點統計信息傳輸到流言消息中,以改善有關扇出的本地決策制定。

諸如隊列深度、關鍵元數據(如配置更改)甚至請求-響應之類的子系統信息可以通過流言協議傳輸。通過流言協議聚合節點更新消息允許以單個塊發送數據,而不是多個小消息,以減少通信開銷。

通過識別節點的活動性,可以跨集羣最優地路由消息。在不涉及集中式服務的情況下,在本地節點級別進行決策制定是擴展流言協議的關鍵。可以使用向量時鐘對消息進行版本控制,以便節點通過向量時鐘忽略舊的消息版本。使用流言協議的一些常見組件如下:

  • Apache Cassandra 使用流言協議維護集羣成員資格,傳輸節點元數據(令牌分配)
  • Consul 使用 swim-gossip 協議變體進行組員資格、領導者選舉和 consul 代理的故障檢測
  • CockroachDB 操作流言協議來傳播節點元數據
  • Amazon S3 使用流言協議在系統中傳播服務器狀態
  • Redis 集羣使用流言協議傳播節點元數據

流言協議優勢

流言協議具有以下優勢:

  • 可擴展性
  • 容錯性
  • 魯棒性
  • 一致性
  • 去中心化
  • 有界負載

可擴展性

可擴展性是系統在處理不斷增加的負載時不降低性能的能力。流言協議循環需要對數時間來實現收斂。此外,每個節點只與固定數量的節點進行交互,並獨立於系統中節點的數量發送固定數量的消息。節點不會等待確認以提高延遲。

容錯性

容錯性是系統在發生故障(如節點崩潰、網絡分區或消息丟失)時仍能保持功能的能力。採用流言協議的分佈式系統具有容錯性,因爲它能夠容忍不可靠的網絡。流言協議提供的冗餘、並行性和隨機性提高了系統的容錯性。

此外,節點的對稱性和去中心化特性增強了流言協議的容錯性[5]。相同的消息通常通過多個節點多次傳輸。換句話說,消息在源點和目的地之間有許多路由。因此,通過另一個節點的消息傳輸可以克服節點故障。

魯棒性

參與流言協議的節點的對稱性質提高了系統的魯棒性。節點故障不會破壞系統質量。流言協議還對瞬態網絡分區具有魯棒性。然而,除非數據自驗證,否則流言協議對故障節點或惡意流言消息並不魯棒。

可以使用基於分數的節點聲譽系統來防止惡意節點破壞流言系統。必須實施適當的機制和政策,如加密、認證和授權,以強制執行流言系統的隱私和安全。

一致性

一致性是確保系統中每個節點都有相同狀態視圖的技術。不同的一致性級別,如強一致性、最終一致性、因果一致性和概率一致性,對系統的性能、可用性和正確性有不同的影響。通過數據的指數級傳播,流言協議以對數時間複雜度收斂到最終一致狀態。

去中心化

流言協議提供了一個通過對等通信進行信息發現的極端去中心化模型。

有界負載

經典的分佈式系統協議通常會產生高突增負載,可能會使單個分佈式系統組件超載。流言協議將對單個分佈式系統組件產生嚴格有界的最壞情況負載,以避免破壞服務質量。流言協議中的對等節點選擇可以調整以減少網絡鏈路上的負載。在實踐中,流言協議產生的負載不僅是有界的,而且與可用帶寬相比也是微不足道的。

流言協議缺點

當然,事物都有兩面性,流言協議的也存在如下一些缺點:

  • 最終一致性
  • 對網絡分區不敏感
  • 相對較高的帶寬消耗
  • 增加延遲
  • 調試和測試困難
  • 成員協議不可擴展
  • 容易計算錯誤

最終一致性

流言協議本質上是最終一致的。與多播相比,流言協議會相對較慢。與流言消息相關的開銷以及流言行爲取決於網絡拓撲和節點異構性。因此,集羣識別新節點或節點故障會有一定的延遲。

網絡分區不敏感

當發生網絡分區時,子分區中的節點仍將相互流言。因此,流言協議對網絡分區不敏感,可能會顯著延遲消息傳播。

帶寬

流言協議並不以效率著稱,因爲相同的消息可能會多次重新傳輸到同一節點,消耗不必要的帶寬。儘管由於有界消息大小和消息的週期性交換,流言協議的帶寬使用受到限制,但當節點應該流言的信息量超過有界消息大小時,通過流言交換的有效扇出可能會降低。

流言協議的飽和點取決於不同的參數,如消息生成速率、消息大小、扇出和流言協議的類型。

延遲

使用流言協議會導致延遲增加,因爲節點必須等待下一個流言週期(間隔)來傳輸消息。消息不會觸發流言交換,但流言協議間隔計時器會。將消息傳播到系統所需的時間複雜度是 O(log n)。

調試和測試

調試是識別和修復導致流言協議偏離預期行爲的故障。測試是驗證流言協議是否滿足功能和非功能要求(如性能、可靠性和安全性)的能力。

流言協議固有的非確定性和分佈式特性使其難以調試和重現故障。調試驗證時可以使用模擬、仿真、日誌記錄、跟蹤、監控和可視化等工具和技術來測試和調試流言系統。

可擴展性

大多數流言協議的變體依賴於一個不可擴展的成員協議。

計算錯誤

由於惡意節點,流言協議傾向於計算錯誤。節點應實現自我糾錯機制,因爲流言協議的魯棒性僅限於某些故障類別。儘管如此,流言協議非常可靠,具有概率爲一的結果很常見。

總結

在分佈式系統中,流言是一件好事,而在現實世界中就不一定了。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章