今天打算寫寫關(guān)于 IM 去中心化涉及的架構(gòu)模型變化和設(shè)計思路,去中心化的概念就是說用戶的訪問不是集中在一個數(shù)據(jù)中心阿趁,這里的去中心是針對數(shù)據(jù)中心而言的僵芹。
站在這個角度而言,實際上并非所有的業(yè)務(wù)都能做去中心化設(shè)計霉咨,對于一致性要求越高的業(yè)務(wù)去中心化越難做蛙紫。比如電商領(lǐng)域的庫存就是一個對一致性要求很高的業(yè)務(wù),不能超賣也不能少賣途戒,這在單中心容易實現(xiàn)坑傅,但多中心純從技術(shù)層面感覺無解,可能需要從業(yè)務(wù)和技術(shù)層面一起去做個折衷喷斋。
反過來看 IM 的業(yè)務(wù)場景是非常適合做去中心化設(shè)計的唁毒,因為其業(yè)務(wù)場景都是弱一致性需求蒜茴。打開你的微信或 QQ 仔細(xì)觀察下,對大部分人來說與你聯(lián)系最頻繁的實際多是在地域上離你最近的人浆西,人與人之間的心理距離和物理距離會隨著時間漸趨保持一致粉私。所以根據(jù)這個特點,按地域來分布數(shù)據(jù)中心和聚合人群是比較合適的近零。
在進(jìn)入去中心化 IM 架構(gòu)模型之前毡鉴,我們先看看中心化架構(gòu)是怎樣的,分析其關(guān)鍵設(shè)計再來看如果要去中心化需要做哪些變化秒赤?
中心化
IM 的中心化架構(gòu)并不意味著只有一個數(shù)據(jù)中心猪瞬,它也可以是多數(shù)據(jù)中心的,如下圖入篮。
之所以說它是中心化架構(gòu)陈瘦,關(guān)鍵特征是其存在共享的數(shù)據(jù)存儲。部署在兩個數(shù)據(jù)中心的應(yīng)用需要共享訪問統(tǒng)一的數(shù)據(jù)存儲潮售,而這種共享訪問實際是依賴數(shù)據(jù)中心之間的專線連通痊项,這樣的架構(gòu)也限制了能選取的數(shù)據(jù)中心地理位置的距離。而實現(xiàn)去中心架構(gòu)的關(guān)鍵點就在于規(guī)避跨數(shù)據(jù)中心的共享存儲訪問酥诽,使得應(yīng)用在其自身數(shù)據(jù)中心實現(xiàn)訪問閉環(huán)鞍泉。
我們這里只分析下實現(xiàn) IM 消息互通這個最重要場景下共享數(shù)據(jù)存儲里需要存些什么數(shù)據(jù)呢?一個是用戶上線后的「座標(biāo)」肮帐,主要指用戶本次在線接入了哪臺機(jī)器的哪根連接咖驮,這個「座標(biāo)」用于在線消息投遞。而另一方面若用戶離線時训枢,別人給它發(fā)消息托修,這些消息也需要存儲下來,一般稱為用戶的「離線消息」恒界,下次用戶上線就可以自動收取自己的離線消息睦刃。
中心化架構(gòu)實際能做到的極致就是把讀實現(xiàn)自有數(shù)據(jù)中心閉環(huán),而寫依然需要向主數(shù)據(jù)中心所在的存儲寫入十酣。而 IM 的寫入場景還不算是一個低頻操作涩拙,那么要實現(xiàn)去中心化架構(gòu)關(guān)鍵點就在如何解決寫的問題上。
去中心化
在設(shè)計 IM 的去中心化架構(gòu)之前耸采,希望去實現(xiàn)這個架構(gòu)并編寫代碼時兴泥,不需要去考慮最終部署到底是去中心的還是中心的。編碼時就像開發(fā)中心化架構(gòu)一樣去實現(xiàn)場景的功能洋幻,而去中心化的能力做為純基礎(chǔ)的技術(shù)能力郁轻,通過附加的方式來獲得,先看看架構(gòu)圖的變化,如下好唯。
這里的變化是為「座標(biāo)」增加一個「數(shù)據(jù)中心」緯度竭沫,當(dāng)按通用的方式去本地存儲定位用戶時,發(fā)現(xiàn)一個非本地的座標(biāo)時消息該怎么投遞骑篙?這里可以在每個本地數(shù)據(jù)中心額外添加一個消息網(wǎng)關(guān)程序蜕提,注冊到本地存儲中,并負(fù)責(zé)接收所有非本地座標(biāo)的消息靶端,這有點像路由網(wǎng)絡(luò)中的邊界網(wǎng)關(guān)谎势。
消息網(wǎng)關(guān)統(tǒng)一接收應(yīng)當(dāng)發(fā)往其他數(shù)據(jù)中心的消息,以實現(xiàn)跨數(shù)據(jù)中心的消息流轉(zhuǎn)杨名。這里有個疑問是其他數(shù)據(jù)中心的「座標(biāo)」是怎么跑到本地來的脏榆?離線消息的場景又該如何處理呢?關(guān)于這兩個問題台谍,就涉及到我們解決跨數(shù)據(jù)中心同步數(shù)據(jù)的關(guān)鍵技術(shù)了须喂。
關(guān)鍵技術(shù)
結(jié)合 IM 的業(yè)務(wù)場景,實際它對同步的延時具有一定的容忍度趁蕊。所以我覺得基于 Gossip 協(xié)議的小道消息傳播特性就能很好的滿足這個同步場景坞生。
關(guān)于 Gossip 我是在新近的 NoSQL 數(shù)據(jù)庫 Cassandra 上聽說的,后來 Redis Cluster 也利用了該協(xié)議來實現(xiàn)無中心化集群架構(gòu)掷伙。但 Gossip 協(xié)議可不是什么新東西是己,實際關(guān)于它的誕生可以追溯到好幾十年前的施樂研究中心,就是為了解決數(shù)據(jù)庫同步問題被我們的前前前輩想出來的任柜。
這個協(xié)議的靈感來自于辦公室小道消息的傳播路徑卒废,當(dāng)一個人知道了一條小道消息,他碰到一個朋友并隨口告訴了他乘盼,朋友又告訴了朋友的朋友升熊,沒多久整個辦公室都知道了,也就完成了信息的同步绸栅。借用這個模型,實際上我們需要同步的信息就是用戶的在線「座標(biāo)」和「離線消息」页屠。
因為 Gossip 自好幾十年前已經(jīng)有很多論文證明并公開發(fā)表粹胯,而且近年也有 Cassandra 和 Redis 的成功工程實踐,所以我就先不用去懷疑其可行性辰企,而是直接利用其結(jié)論了。根據(jù)其特性,分析 IM 的去中心場景在引入 Gossip 后有些什么可供觀察的變化和值得注意的方面昔搂。
在一個稍具規(guī)模的 IM 場景下拍嵌,用戶總是在上上下下,消息也在不停的在「在線」和「離線」之間變化,所以需要通過 Gossip 同步的信息是時時存在的臭增。所以假設(shè)我們在某個時刻去拍一個快照(實際做不到)懂酱,得到的結(jié)果是多個數(shù)據(jù)中心的數(shù)據(jù)肯定是不一致的,幾乎不存在所謂的全局最終一致性的某一時刻誊抛。在這樣的客觀環(huán)境下列牺,對 IM 的業(yè)務(wù)場景有多大影響?
當(dāng)用戶A在 IDC#1 在線拗窃,用戶B 在 IDC#2 剛上線瞎领,這里存在一個同步時差,那么此時用戶A給用戶B發(fā)消息随夸,在本地沒有用戶B的座標(biāo)九默,所以進(jìn)入離線消息池。用戶B此時不能立刻收到用戶A的消息宾毒,但離線消息池會在隨后通過 Gossip 協(xié)議同步到用戶B所在的 IDC#2荤西,用戶B此時就可以通過離線消息收取用戶A的消息。
上面描述了一種臨界場景伍俘,在這種臨界場景下邪锌,用戶收消息存在延時。而這種臨界場景實際上并不是常態(tài)癌瘾,而且 IM 用戶實際對這種剛上線的消息延時存在很高的容忍度觅丰。這一點我想大家用 QQ 可能體會過,有時一上線都一分鐘了妨退,還會收到之前的離線消息妇萄,我不知道這是有意的延時還是真有這么長的系統(tǒng)延時。
那么使用 Gossip 協(xié)議從理論上來估算下會產(chǎn)生多久的延時咬荷?假設(shè)我們在全國東西南北中各部署一個數(shù)據(jù)中心冠句,一共五個。五個數(shù)據(jù)中心之間無專線幸乒,走公網(wǎng)互通懦底,網(wǎng)絡(luò)延時最大 200 ms。使用 Gossip 完成在五個數(shù)據(jù)中心的最終一致性同步最大需要多長時間罕扎?這里我直接引用 Gossip 論文結(jié)論:
Cycles = log(N) + ln(N) + O(1)
當(dāng) N=5 時聚唐,完成全部同步,需要節(jié)點間私下傳播的次數(shù)腔召,套用公式得到 3.3 次杆查,取整得 4 次。按最大網(wǎng)絡(luò)延時 200 ms臀蛛,每次 Gossip 交換信息間隔 100 ms亲桦,那么協(xié)議本身固有延時大約 4x200 + 4x100 = 1.2s崖蜜,而再算上程序開銷,這個延時很可能在數(shù)秒內(nèi)波動客峭,這個量級的延時對于少數(shù)的臨界場景是完全可以接受的豫领。
總結(jié)
本文的標(biāo)題是概念模型,但它不像另外一篇《RPC 的概念模型與實現(xiàn)解析》跟了實現(xiàn)解析桃笙,說明這只是一個理論推導(dǎo)氏堤。因為里面最關(guān)鍵的是如何配合 Gossip 的共享存儲似乎沒有找到特別適合的產(chǎn)品,要是自己做一個呢就會產(chǎn)生一種今天只想出去兜兜風(fēng)搏明,卻要先自己動手造輛車的感覺鼠锈。
參考
[1]. Wikipedia. Gossip protocol. 2016.03.29
[2]. ALVARO VIDELA. GOSSIP PROTOCOLS, WHERE TO START. 2015.12.02
[3]. Anne-Marie et al. Gossiping in Distributed Systems. 2007
[4]. Márk Jelasity. Gossip Protocols
[5]. Alberto Montresor. Gossip protocols for large-scale distributed systems. 2010