一、背景
我是一個小病毒,其他病毒都叫我小 B,我長得就是下圖這個樣子了。
我現在已經有 100 nm 大小了,我還有很多觸角,人類把我的觸角稱爲冠
,所以給我起了個學術名:冠狀病毒
。對於這個學術名,我一直不滿意,怎麼能用外貌來取名呢,這是以貌取毒
。
我出生在一個蝙蝠身上,每到晚上,這隻動物就到處覓食,它最喜歡的就是在森林中覓食,但最近森林的範圍急劇減少,它不得不到人類居住的城市來覓食,看着五顏六色的燈光,我如癡如醉。
這隻蝙蝠攜帶了 100 多種病毒,比如埃博拉
病毒、MERS
病毒,我每天和這些病毒一起嬉戲遊玩。SARS 病毒
是我的近親,2002 年的時候,它還造成了一次不小的傳染病疫情,轟動了整個病毒界,人類稱它爲非典
。
二、意外
這天晚上,烏雲密佈,空氣混濁,蝙蝠飛到了密林深處,突然渾身被一股電流擊中,猝然倒地,一隻大網將其捕獲,隨之而來的是穿着一襲黑色大衣的人類把蝙蝠關進了籠子裏面。
隨後的幾天,蝙蝠一直被關在籠子裏面,直到有一天,蝙蝠被帶到了一個隨處可見野生動物的地方,但這些動物要麼是被粗繩綁起來了,要麼是被關在鐵籠裏。一個肥頭大耳的人類走進了蝙蝠,他將手裏攢着的一大疊鈔票
給了黑衣人後,帶走了蝙蝠。
蝙蝠可能與肥頭大耳的人類走得太近,我被傳到了人類的的手
上,隨後又通過他接觸的食物
進入到了他的口
中,進而進入到了他的體內。
三、種子節點
進入到人體中後,我欺騙了人類的免疫系統
,順利進入到人體細胞中,釋放自己的 RNA
,通過正常細胞的 RNA 聚合酶
來複制自己的 RNA,從而複製
出更多的病毒,進而攻擊
人體肺部器官。
過了幾天後,這名人類出現了發燒
現象,同時伴有咳嗽
症狀,而我的同伴也通過噴嚏
傳到了其他人體中,同樣開始大量複製
自己。
一傳十,十傳百,這個地級市已有數千名人類被病毒感染。而我就被稱作種子節點
,而那名人類被稱作零號病人
。
四、Gossip 協議
人體內的正常細胞對我的傳染性非常感興趣。
正常細胞:“冠狀大哥,你是怎麼這麼快進行傳播的啊?”
我:“其實我是利用了
Gossip
協議。”我:Gossip 主要有三大功能,直接郵寄、反熵、謠言傳播。
Gossip 的中文意思就是流言蜚語
,該協議就像流言蜚語一樣,利用一種隨機
、帶有傳染性
的方式,將信息傳播到整個網絡中,並在一定時間內,使得系統內的所有節點數據一致
。這個就是實現了最終一致性
的協議。
4.1 直接郵寄
直接發送需要更新的數據到其他節點,當數據發送失敗
時,將數據緩存
下來,然後重傳
。如下圖所示,人類 A 直接將病毒傳染給了 C 和 E,而 B 和 D 沒有被感染到,需要重新傳染。
優點:實現容易,數據同步及時。
缺點:可能會因爲重試的緩存隊列滿了而丟數據。無法實現最終一致性。
那如何實現最終一致性呢?那就要用到第二種功能了:反熵
。
4.2 反熵
反熵
這個名詞怎麼理解呢?
熵
指混亂程度,反熵
就是消除
不同節點間數據的差異
,提升
節點間數據的相似度
。
反熵的過程:
- (1)集羣中的節點,每隔段時間就隨機選擇某個其他節點。
- (2)互相交換自己的所有數據來消除兩者之間的差異。
- (3)實現數據的最終一致性。
下面舉個病毒傳染的例子來說明反熵。
首先人類 A 被感染了兩種病毒,分別是病毒 T 和病毒 R,如下圖所示:
人類 E 被感染了三種病毒,分別是病毒 T、病毒 S、病毒 Y,如下圖所示:
人類 A 將攜帶的病毒 T 和 R 傳染給了人類 E,而 E 本來就攜帶了病毒 T,所以最後會被傳染四種病毒:T、S、Y、R。也就是說通過反熵的方式,修復了人類 E 中缺失的病毒 R。如下圖所示:
其實,反熵主要有三種方式:推、拉、推和拉
。
4.2.1 推
推:將自己的副本數據推給對象,修復對方副本中的熵。
如下圖所示,人類 A 將病毒 R 傳染(推
)給了人類 E,E 中就包含所有 A 的病毒了。
4.2.2 拉
拉:拉取對方中的所有副本數據,修復自己副本中的熵。
如下圖所示:人類 A 只有病毒 T 和 R,經過主動拉
方式後,將人類 E 的病毒 S 和 病毒 Y 同步到人類 A 身上了,最後,人類 A 攜帶四種病毒:T、R、S、Y。
4.2.3 推拉
推拉:同時修復自己副本和對象副本中的熵。
如下圖所示:人類 A 和 人類 E 通過推拉的方式最後都被感染了相同的四種病毒:T、R、S、Y。
4.2.4 反熵的缺點
(1)通過上面推、拉、推拉的方式,我們可以主要到,反熵是需要節點兩兩交換和比對自己所有的數據,這樣來看的話,通訊成本是很高的,所以不建議實際場景中頻繁地執行反熵。
那有沒有辦法來減少反熵的次數呢?
答案是有的,我們可以通過引入校驗和等機制來降低需要對比的數據量和通訊信息。
(2)執行反熵時,相關節點都是已知的,且節點數量不能太多。如果節點動態變化或節點數過多,反熵就不合適。
那有沒有辦法來解決動態、多節點的最終一致性呢?
答案是有的,那就要用到 Gossip 協議的第三種傳播功能了,謠言傳播或者叫流行病傳播。
4.3 流行病傳播
4.3.1 過程
Gossip 協議的第三種傳播功能,流行病傳播,也就是廣泛地散播病毒。
如下圖所示:A 傳染給了 B 和 E,B 傳染給了 C 和 D,D 傳染給了 F 和 G。最後 ABCDEFG 都被感染了。
在分佈式系統中,當一個節點有了新數據後,這個節點變成活躍狀態,並週期性地聯繫其他節點向其發送新數據,直到所有節點都存儲了該數據,可以理解爲之前講的反熵中的推
的方式。如下圖所示:
4.3.2 缺點
流行病傳播的方式有如下缺點:
- 時間隨機:所有節點達到一致性是一個隨機性的概率。可以改進反熵的流程:使用閉環修復。
- 消息冗餘:同一節點會多次接收同一消息,增加消息處理的壓力,每一次通信都會對網絡帶寬、CPU 資源造成負載,進而影響達到最終一致性的時間。
- 拜占庭問題:如果有惡意節點出現,那麼其他節點也會出問題。所以需要先修復故障節點。
4.3.3 優點
- 支持動態、多節點:允許動態增加或減少節點,支持非常多的節點。
- 大多數節點:不需要大多數節點正常運行也能達到最終一致性
- 容錯:任何節點重啓或宕機都不會影響 Gossip 協議的運行,天然的分佈式系統容錯特性。
- 去中心化:節點都是對等的,沒有特殊節點。任何節點出現問題都不會阻止其他節點繼續執行反熵。
- 速度快:因爲每個節點都可以進行傳播,所以速度是指數級的,就像現在的新冠病毒一樣。
因爲 Gossip 協議是一個帶冗餘的容錯算法,爲了保證最終一致性的算法。雖然所有節點達到一致的時間點不明確,但也可以通過改進反熵的執行過程來達到可預測,比如閉環反熵(不在本文展開論述)。
五、總結
本文通過一個攜帶冠狀病毒的蝙蝠傳染人類的故事來講解了 Gossip 協議。
-
Gossip 協議是一種
異步修復
、實現最終一致性
的協議。優先考慮反熵。 -
反熵在
存儲組件
中用得比較多。比如 Cassandra、InfluxDB。 -
謠言傳播(流行病傳播)具有傳染性,節點之間
相互傳染
。適合動態變化
的分佈式系統
。比如 Cassandra 動態管理集羣的節點狀態。 -
實際場景,
直接郵寄
一定要實現,性能損耗最低。通過發送更新數據或緩存重傳就能修復數據的不一致。 -
在存儲組件中,節點已知,採用
反熵
修復數據副本的不一致。 -
集羣節點變化時,或節點較多時,採用
謠言傳播
方式,來同步更新多節點的數據,來實現最終一致性。 -
Gossip 的三種功能其實都是爲了實現反熵,第一種用消息隊列,第二種用推拉消息,第三種用散播謠言。
-
如果節點出現
故障
,需要先修復故障節點。
作者簡介:8 年互聯網經驗,擅長架構設計、分佈式、微服務。公衆號:悟空聊架構,用故事講解分佈式、微服務。
《7 個實驗精通 JVM 性能調優》專欄作者。
手寫了一套 SpringCloud 實戰教程,自主開發了 PMP 刷題小程序和 Java 刷題小程序。關注公衆號:悟空聊架構,回覆 pdf 領取。