Gossip病毒協(xié)議 以及冪等處理

背景

Gossip protocol 也叫 Epidemic Protocol (流行病協(xié)議),實際上它還有很多別名翠忠,比如:“流言算法”鞠苟、“疫情傳播算法”等。

這個協(xié)議的作用就像其名字表示的意思一樣秽之,非常容易理解当娱,它的方式其實在我們日常生活中也很常見,比如電腦病毒的傳播考榨,森林大火趾访,細胞擴散等等。

Gossip protocol 最早是在 1987 年發(fā)表在 ACM 上的論文 《Epidemic Algorithms for Replicated Database Maintenance》中被提出董虱。主要用在分布式數據庫系統(tǒng)中各個副本節(jié)點同步數據之用扼鞋,這種場景的一個最大特點就是組成的網絡的節(jié)點都是對等節(jié)點,是非結構化網絡愤诱,這區(qū)別與之前介紹的用于結構化網絡中的 DHT 算法 Kadmelia云头。

我們知道,很多知名的 P2P 網絡或區(qū)塊鏈項目淫半,比如 IPFS溃槐,Ethereum 等,都使用了 Kadmelia 算法科吭,而大名鼎鼎的 Bitcoin 則是使用了 Gossip 協(xié)議來傳播交易和區(qū)塊信息昏滴。

實際上,只要仔細分析一下場景就知道对人,Ethereum 使用 DHT 算法并不是很合理谣殊,因為它使用節(jié)點保存整個鏈數據,不像 IPFS 那樣分片保存數據牺弄,因此 Ethereum 真正適合的協(xié)議應該像 Bitcoin 那樣姻几,是 Gossip 協(xié)議。

這里先簡單介紹一下 Gossip 協(xié)議的執(zhí)行過程:

Gossip 過程是由種子節(jié)點發(fā)起势告,當一個種子節(jié)點有狀態(tài)需要更新到網絡中的其他節(jié)點時蛇捌,它會隨機的選擇周圍幾個節(jié)點散播消息,收到消息的節(jié)點也會重復該過程咱台,直至最終網絡中所有的節(jié)點都收到了消息络拌。這個過程可能需要一定的時間,由于不能保證某個時刻所有節(jié)點都收到消息回溺,但是理論上最終所有節(jié)點都會收到消息春贸,因此它是一個最終一致性協(xié)議混萝。

Gossip 演示

現(xiàn)在,我們通過一個具體的實例來深入體會一下 Gossip 傳播的完整過程

為了表述清楚祥诽,我們先做一些前提設定

1、Gossip 是周期性的散播消息瓮恭,把周期限定為 1 秒

2雄坪、被感染節(jié)點隨機選擇 k 個鄰接節(jié)點(fan-out)散播消息,這里把 fan-out 設置為 3屯蹦,每次最多往 3 個節(jié)點散播维哈。

3、每次散播消息都選擇尚未發(fā)送過的節(jié)點進行散播

4登澜、收到消息的節(jié)點不再往發(fā)送節(jié)點散播阔挠,比如 A -> B,那么 B 進行散播的時候脑蠕,不再發(fā)給 A购撼。

注意:Gossip 過程是異步的,也就是說發(fā)消息的節(jié)點不會關注對方是否收到谴仙,即不等待響應迂求;不管對方有沒有收到,它都會每隔 1 秒向周圍節(jié)點發(fā)消息晃跺。異步是它的優(yōu)點揩局,而消息冗余則是它的缺點。

這里一共有 16 個節(jié)點掀虎,節(jié)點 1 為初始被感染節(jié)點凌盯,通過 Gossip 過程,最終所有節(jié)點都被感染:

image

Gossip 的特點(優(yōu)勢)

1)擴展性

網絡可以允許節(jié)點的任意增加和減少烹玉,新增加的節(jié)點的狀態(tài)最終會與其他節(jié)點一致驰怎。

2)容錯

網絡中任何節(jié)點的宕機和重啟都不會影響 Gossip 消息的傳播,Gossip 協(xié)議具有天然的分布式系統(tǒng)容錯特性二打。

3)去中心化

Gossip 協(xié)議不要求任何中心節(jié)點砸西,所有節(jié)點都可以是對等的,任何一個節(jié)點無需知道整個網絡狀況址儒,只要網絡是連通的芹枷,任意一個節(jié)點就可以把消息散播到全網。

4)一致性收斂

Gossip 協(xié)議中的消息會以一傳十莲趣、十傳百一樣的指數級速度在網絡中快速傳播鸳慈,因此系統(tǒng)狀態(tài)的不一致可以在很快的時間內收斂到一致。消息傳播速度達到了 logN喧伞。

5)簡單

Gossip 協(xié)議的過程極其簡單走芋,實現(xiàn)起來幾乎沒有太多復雜性绩郎。

Márk Jelasity 在它的 Gossip一書中對其進行了歸納:

image

Gossip 的缺陷

分布式網絡中,沒有一種完美的解決方案翁逞,Gossip 協(xié)議跟其他協(xié)議一樣肋杖,也有一些不可避免的缺陷,主要是兩個:

1)消息的延遲

由于 Gossip 協(xié)議中挖函,節(jié)點只會隨機向少數幾個節(jié)點發(fā)送消息状植,消息最終是通過多個輪次的散播而到達全網的,因此使用 Gossip 協(xié)議會造成不可避免的消息延遲怨喘。不適合用在對實時性要求較高的場景下津畸。

2)消息冗余

Gossip 協(xié)議規(guī)定,節(jié)點會定期隨機選擇周圍節(jié)點發(fā)送消息必怜,而收到消息的節(jié)點也會重復該步驟肉拓,因此就不可避免的存在消息重復發(fā)送給同一節(jié)點的情況,造成了消息的冗余梳庆,同時也增加了收到消息的節(jié)點的處理壓力暖途。而且,由于是定期發(fā)送膏执,因此丧肴,即使收到了消息的節(jié)點還會反復收到重復消息,加重了消息的冗余胧后。

Gossip 類型

Gossip 有兩種類型:

  • Anti-Entropy(反熵):以固定的概率傳播所有的數據
  • Rumor-Mongering(謠言傳播):僅傳播新到達的數據

Anti-Entropy 是 SI model芋浮,節(jié)點只有兩種狀態(tài),Suspective 和 Infective壳快,叫做 simple epidemics纸巷。

Rumor-Mongering 是 SIR model,節(jié)點有三種狀態(tài)眶痰,Suspective瘤旨,Infective 和 Removed,叫做 complex epidemics竖伯。

其實存哲,Anti-entropy 反熵是一個很奇怪的名詞,之所以定義成這樣七婴,Jelasity 進行了解釋祟偷,因為 entropy 是指混亂程度(disorder),而在這種模式下可以消除不同節(jié)點中數據的 disorder打厘,因此 Anti-entropy 就是 anti-disorder修肠。換句話說,它可以提高系統(tǒng)中節(jié)點之間的 similarity户盯。

在 SI model 下嵌施,一個節(jié)點會把所有的數據都跟其他節(jié)點共享饲化,以便消除節(jié)點之間數據的任何不一致,它可以保證最終吗伤、完全的一致吃靠。

由于在 SI model 下消息會不斷反復的交換,因此消息數量是非常龐大的足淆,無限制的(unbounded)巢块,這對一個系統(tǒng)來說是一個巨大的開銷。

但是在 Rumor Mongering(SIR Model) 模型下缸浦,消息可以發(fā)送得更頻繁夕冲,因為消息只包含最新 update氮兵,體積更小裂逐。而且,一個 Rumor 消息在某個時間點之后會被標記為 removed泣栈,并且不再被傳播卜高,因此,SIR model 下南片,系統(tǒng)有一定的概率會不一致掺涛。

而由于,SIR Model 下某個時間點之后消息不再傳播疼进,因此消息是有限的薪缆,系統(tǒng)開銷小。

Gossip 中的通信模式

在 Gossip 協(xié)議下伞广,網絡中兩個節(jié)點之間有三種通信方式:

  • Push: 節(jié)點 A 將數據 (key,value,version) 及對應的版本號推送給 B 節(jié)點拣帽,B 節(jié)點更新 A 中比自己新的數據
  • Pull:A 僅將數據 key, version 推送給 B,B 將本地比 A 新的數據(Key, value, version)推送給 A嚼锄,A 更新本地
  • Push/Pull:與 Pull 類似减拭,只是多了一步,A 再將本地比 B 新的數據推送給 B区丑,B 則更新本地

如果把兩個節(jié)點數據同步一次定義為一個周期拧粪,則在一個周期內,Push 需通信 1 次沧侥,Pull 需 2 次可霎,Push/Pull 則需 3 次。雖然消息數增加了宴杀,但從效果上來講啥纸,Push/Pull 最好,理論上一個周期內可以使兩個節(jié)點完全一致婴氮。直觀上斯棒,Push/Pull 的收斂速度也是最快的盾致。

復雜度分析

對于一個節(jié)點數為 N 的網絡來說,假設每個 Gossip 周期荣暮,新感染的節(jié)點都能再感染至少一個新節(jié)點庭惜,那么 Gossip 協(xié)議退化成一個二叉樹查找,經過 LogN 個周期之后穗酥,感染全網护赊,時間開銷是 O(LogN)。由于每個周期砾跃,每個節(jié)點都會至少發(fā)出一次消息骏啰,因此,消息復雜度(消息數量 = N * N)是 O(N^2) 抽高。注意判耕,這是 Gossip 理論上最優(yōu)的收斂速度,但是在實際情況中翘骂,最優(yōu)的收斂速度是很難達到的壁熄。

假設某個節(jié)點在第 i 個周期被感染的概率為 pi,第 i+1 個周期被感染的概率為 pi+1 碳竟,

1)則 Pull 的方式:

image

2)Push 方式:

image

顯然 Pull 的收斂速度大于 Push 草丧,而每個節(jié)點在每個周期被感染的概率都是固定的 p (0<p<1),因此 Gossip 算法是基于 p 的平方收斂莹桅,也稱為概率收斂昌执,這在眾多的一致性算法中是非常獨特的。

冪等處理
一诈泼、背景

  1. 前端重復提交選中的數據懂拾,應該后臺只產生對應這個數據的一個反應結果。
    2. 我們發(fā)起一筆付款請求厂汗,應該只扣用戶賬戶一次錢委粉,當遇到網絡重發(fā)或系統(tǒng)bug重發(fā),也應該只扣一次錢娶桦;
    3. 發(fā)送消息贾节,也應該只發(fā)一次,同樣的短信發(fā)給用戶衷畦,用戶會哭的栗涂;
    4. 創(chuàng)建業(yè)務訂單,一次業(yè)務請求只能創(chuàng)建一個祈争,創(chuàng)建多個就會出大問題斤程。

二、什么事冪等

一個操作,不論執(zhí)行多少次忿墅,產生的效果和返回的結果都是一樣的

同樣一個請求連續(xù)發(fā)兩遍(請求的參數可能有細微不一樣扁藕,比如時間戳,但是對后臺來說這應該屬于同一個請求)疚脐,想達到的目的是:兩個請求同時到達的時候只有一個請求在執(zhí)行亿柑,另外一個請求等待第一個請求結束,并返回相同結果棍弄。這就是冪等的意思望薄。

三、實現(xiàn)冪等有哪些思路

1. 查詢操作

查詢一次和查詢多次呼畸,在數據不變的情況下痕支,查詢結果是一樣的。select是天然的冪等操作

2. 刪除操作

刪除操作也是冪等的蛮原,刪除一次和多次刪除都是把數據刪除卧须。(注意可能返回結果不一樣,刪除的數據不存在瞬痘,返回0故慈,刪除的數據多條板熊,返回結果多個)

3.唯一索引框全,防止新增臟數據

比如:支付寶的資金賬戶,支付寶也有用戶賬戶干签,每個用戶只能有一個資金賬戶津辩,怎么防止給用戶創(chuàng)建資金賬戶多個,那么給資金賬戶表中的用戶ID加唯一索引容劳,所以一個用戶新增成功一個資金賬戶記錄

要點:

唯一索引或唯一組合索引來防止新增數據存在臟數據

(當表存在唯一索引喘沿,并發(fā)時新增報錯時,再查詢一次就可以了竭贩,數據應該已經存在了蚜印,返回結果即可)

4. token機制,防止頁面重復提交

業(yè)務要求:

頁面的數據只能被點擊提交一次

發(fā)生原因:

由于重復點擊或者網絡重發(fā)留量,或者nginx重發(fā)等情況會導致數據被重復提交

解決辦法:

集群環(huán)境:采用token加redis(redis單線程的窄赋,處理需要排隊)

單JVM環(huán)境:采用token加redis或token加jvm內存

處理流程:

1. 數據提交前要向服務的申請token,token放到redis或jvm內存楼熄,token有效時間

2. 提交后后臺校驗token忆绰,同時刪除token,生成新的token返回

token特點:

要申請可岂,一次有效性错敢,可以限流

注意:redis要用刪除操作來判斷token,刪除成功代表token校驗通過缕粹,如果用select+delete來校驗token稚茅,存在并發(fā)問題纸淮,不建議使用

5. 悲觀鎖

獲取數據的時候加鎖獲取

select * from table_xxx where id='xxx' for update;

注意:id字段一定是主鍵或者唯一索引,不然是鎖表亚享,會死人的

悲觀鎖使用時一般伴隨事務一起使用萎馅,數據鎖定時間可能會很長,根據實際情況選用

6. 樂觀鎖

樂觀鎖只是在更新數據那一刻鎖表虹蒋,其他時間不鎖表糜芳,所以相對于悲觀鎖,效率更高魄衅。

樂觀鎖的實現(xiàn)方式多種多樣可以通過version或者其他狀態(tài)條件:

1). 通過版本號實現(xiàn)

update table_xxx set name=#name#,version=version+1 where version=#version#

2). 通過條件限制

update table_xxx set avai_amount=avai_amount-#subAmount# where avai_amount-#subAmount# >= 0

要求:quality-#subQuality# >= 峭竣,這個情景適合不用版本號,只更新是做數據安全校驗晃虫,適合庫存模型皆撩,扣份額和回滾份額,性能更高

注意:樂觀鎖的更新操作哲银,最好用主鍵或者唯一索引來更新,這樣是行鎖扛吞,否則更新時會鎖表,上面兩個sql改成下面的兩個更好

update table_xxx set name=#name#,version=version+1 where id=#id# and version=#version#

update table_xxx set avai_amount=avai_amount-#subAmount# where id=#id# and avai_amount-#subAmount# >= 0

7. 分布式鎖

還是拿插入數據的例子荆责,如果是分布是系統(tǒng)滥比,構建全局唯一索引比較困難,例如唯一性的字段沒法確定做院,這時候可以引入分布式鎖盲泛,通過第三方的系統(tǒng)(redis或zookeeper),在業(yè)務系統(tǒng)插入數據或者更新數據键耕,獲取分布式鎖寺滚,然后做操作,之后釋放鎖屈雄,這樣其實是把多線程并發(fā)的鎖的思路村视,引入多多個系統(tǒng),也就是分布式系統(tǒng)中得解決思路酒奶。

要點:某個長流程處理過程要求不能并發(fā)執(zhí)行蚁孔,可以在流程執(zhí)行之前根據某個標志(用戶ID+后綴等)獲取分布式鎖,其他流程執(zhí)行時獲取鎖就會失敗讥蟆,也就是同一時間該流程只能有一個能執(zhí)行成功勒虾,執(zhí)行完成后,釋放分布式鎖(分布式鎖要第三方系統(tǒng)提供)

8. select + insert

并發(fā)不高的后臺系統(tǒng)瘸彤,或者一些任務JOB修然,為了支持冪等,支持重復執(zhí)行,簡單的處理方法是愕宋,先查詢下一些關鍵數據玻靡,判斷是否已經執(zhí)行過,在進行業(yè)務處理中贝,就可以了

注意:核心高并發(fā)流程不要用這種方法

9. 狀態(tài)機冪等

在設計單據相關的業(yè)務囤捻,或者是任務相關的業(yè)務,肯定會涉及到狀態(tài)機(狀態(tài)變更圖)邻寿,就是業(yè)務單據上面有個狀態(tài)蝎土,狀態(tài)在不同的情況下會發(fā)生變更,一般情況下存在有限狀態(tài)機绣否,這時候誊涯,如果狀態(tài)機已經處于下一個狀態(tài),這時候來了一個上一個狀態(tài)的變更蒜撮,理論上是不能夠變更的暴构,這樣的話,保證了有限狀態(tài)機的冪等段磨。

注意:訂單等單據類業(yè)務取逾,存在很長的狀態(tài)流轉,一定要深刻理解狀態(tài)機苹支,對業(yè)務系統(tǒng)設計能力提高有很大幫助

10. 對外提供接口的api如何保證冪等

如銀聯(lián)提供的付款接口:需要接入商戶提交付款請求時附帶:source來源砾隅,seq序列號

source+seq在數據庫里面做唯一索引,防止多次付款沐序,(并發(fā)時琉用,只能處理一個請求
)

轉載于:https://www.cnblogs.com/h-c-g/p/10415048.html

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末堕绩,一起剝皮案震驚了整個濱河市策幼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌奴紧,老刑警劉巖特姐,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異黍氮,居然都是意外死亡唐含,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門沫浆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捷枯,“玉大人,你說我怎么就攤上這事专执』蠢Γ” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長攀痊。 經常有香客問我桐腌,道長,這世上最難降的妖魔是什么苟径? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任案站,我火速辦了婚禮,結果婚禮上棘街,老公的妹妹穿的比我還像新娘蟆盐。我一直安慰自己,他們只是感情好遭殉,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布舱禽。 她就那樣靜靜地躺著,像睡著了一般恩沽。 火紅的嫁衣襯著肌膚如雪誊稚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天罗心,我揣著相機與錄音里伯,去河邊找鬼。 笑死渤闷,一個胖子當著我的面吹牛疾瓮,可吹牛的內容都是我干的。 我是一名探鬼主播飒箭,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼狼电,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弦蹂?” 一聲冷哼從身側響起肩碟,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凸椿,沒想到半個月后削祈,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡脑漫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年髓抑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片优幸。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡吨拍,死狀恐怖,靈堂內的尸體忽然破棺而出网杆,到底是詐尸還是另有隱情羹饰,我是刑警寧澤握爷,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站严里,受9級特大地震影響新啼,放射性物質發(fā)生泄漏。R本人自食惡果不足惜刹碾,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一燥撞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧迷帜,春花似錦物舒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锦针,卻和暖如春荠察,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背奈搜。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工悉盆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人馋吗。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓焕盟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宏粤。 傳聞我的和親對象是個殘疾皇子脚翘,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容