跨地域場(chǎng)景下,如何解決分布式系統(tǒng)的一致性?
跨地域,即常說的“異地雙活”、“異地多活”中的異地概念。在業(yè)務(wù)發(fā)展較快的情況下,我們的服務(wù)便需要跨地域部署,以滿足各區(qū)域就近訪問和跨地域容災(zāi)等需求,在此過程中,不可避免會(huì)涉及到跨地域下的分布式一致性問題。由跨地域所帶來的網(wǎng)絡(luò)延遲問題,以及由于網(wǎng)絡(luò)延遲而衍生的一系列問題,對(duì)于設(shè)計(jì)和構(gòu)建一個(gè)跨地域分布式一致性系統(tǒng)是極大的挑戰(zhàn),業(yè)界有很多針對(duì)此問題的解決方案,都希望能解決跨地域場(chǎng)景下的一致性問題。
本文分享阿里巴巴女媧團(tuán)隊(duì)在跨地域場(chǎng)景下對(duì)分布式一致性系統(tǒng)的探索,從"What How Future"三個(gè)方面,介紹跨地域場(chǎng)景下要承接的需求和挑戰(zhàn)、業(yè)界常見系統(tǒng)和女媧團(tuán)隊(duì)對(duì)于跨地域場(chǎng)景權(quán)衡點(diǎn)的思考,以及對(duì)跨地域一致性系統(tǒng)未來發(fā)展的設(shè)計(jì)與思考,以發(fā)現(xiàn)和解決跨地域場(chǎng)景下更多的需求和挑戰(zhàn)。
一 跨地域需求和挑戰(zhàn)
1 需求
跨地域問題是在集團(tuán)全球化戰(zhàn)略下,業(yè)務(wù)快速發(fā)展帶來的挑戰(zhàn)。像是淘寶單元化業(yè)務(wù),或是AliExpress區(qū)域化業(yè)務(wù),都有一個(gè)無法回避的問題——數(shù)據(jù)跨區(qū)域讀寫一致性。
其核心需求可以總結(jié)為以下幾點(diǎn):
跨地域業(yè)務(wù)場(chǎng)景
跨地域配置同步與服務(wù)發(fā)現(xiàn)是兩個(gè)常見的跨地域一致性協(xié)調(diào)服務(wù)的業(yè)務(wù)需求,跨地域部署可以提供就近訪問能力以減小服務(wù)延遲,根據(jù)具體業(yè)務(wù)場(chǎng)景可分為多地域?qū)懟蚝?jiǎn)化的單地域?qū)?、?qiáng)一致性讀或最終一致性讀等場(chǎng)景??绲赜虻臅?huì)話管理及基于此的跨地域分布式鎖也亟待提供成熟的解決方案。
服務(wù)、資源的拓展問題
當(dāng)一個(gè)地域內(nèi)某個(gè)機(jī)房的服務(wù)能力達(dá)到上限而又無法擴(kuò)容,需要一致性系統(tǒng)在一個(gè)地域多個(gè)機(jī)房水平拓展和能夠跨地域拓展。
跨地域容災(zāi)能力
當(dāng)遭遇機(jī)房或者一個(gè)地域的災(zāi)難性故障時(shí),需要一致性系統(tǒng)通過跨地域服務(wù)部署,將一個(gè)地域的業(yè)務(wù)迅速遷移到另一個(gè)地域完成災(zāi)備逃逸,實(shí)現(xiàn)高可用。
2 挑戰(zhàn)
綜合網(wǎng)絡(luò)延遲和業(yè)務(wù)需求,可以歸納出跨地域一致性系統(tǒng)所需要化解的挑戰(zhàn):
延遲:網(wǎng)絡(luò)延遲達(dá)幾十毫秒
多地域部署帶來的核心問題便是網(wǎng)絡(luò)延遲高,以我們線上跨地域部署的跨地域集群為例,集群中機(jī)器分屬于杭州、深圳、上海、北京四個(gè)地域的機(jī)房,實(shí)際測(cè)試杭州機(jī)房到上海延遲大約6ms,到深圳和北京的延遲可以達(dá)到接近30ms。同機(jī)房或同地域機(jī)房間的網(wǎng)絡(luò)延遲一般在毫秒內(nèi),相比之下跨地域訪問延遲上升了一個(gè)量級(jí)。
水平拓展:Quorum Servers規(guī)模受限
基于Paxos理論及其變種的分布式一致性系統(tǒng),在拓展節(jié)點(diǎn)時(shí)不可避免會(huì)遇到Replication Overhead問題,一般一個(gè)Quorum的節(jié)點(diǎn)數(shù)目不大于9個(gè),故無法簡(jiǎn)單地將一致性系統(tǒng)節(jié)點(diǎn)直接部署在多個(gè)地域,系統(tǒng)需要能持續(xù)地水平拓展,來滿足服務(wù)、資源的拓展需求。
存儲(chǔ)上限:?jiǎn)蝹€(gè)節(jié)點(diǎn)存儲(chǔ)數(shù)據(jù)受限且failover恢復(fù)慢
無論是MySQL還是基于Paxos的一致性系統(tǒng),其單個(gè)節(jié)點(diǎn)都會(huì)維護(hù)和加載全量的鏡像數(shù)據(jù),會(huì)受到單臺(tái)集群容量的限制。同時(shí)在failover恢復(fù)時(shí),若數(shù)據(jù)版本落后較多,通過拉取其他地域鏡像恢復(fù)會(huì)有較長(zhǎng)的不可用時(shí)間。
二 我們的探索
1 業(yè)界解決方案
業(yè)界有針對(duì)跨地域的一致性系統(tǒng)有很多的設(shè)計(jì),主要參考了論文[1]和一些開源的實(shí)現(xiàn),下面介紹常見的幾種:
跨地域部署
圖1 直接跨地域部署
直接跨地域部署,讀請(qǐng)求直接讀本地域節(jié)點(diǎn),速度較快,一致性、可用性由Paxos保證,沒有單點(diǎn)問題。缺點(diǎn)也很明顯,會(huì)遇到第一部分中講到的水平拓展問題,即Quorum拓展時(shí)會(huì)遇到Replication Overhead問題。且隨著Quorum節(jié)點(diǎn)數(shù)目變多,在跨地域極高的網(wǎng)絡(luò)延遲下,每次多數(shù)派達(dá)成一致的時(shí)間會(huì)很長(zhǎng),寫效率很低。
單地域部署+Learner角色
圖2 引入Learner角色
通過引入Learner(例如zk中Observer、etcd的raft learner[2]) 角色,即只進(jìn)行數(shù)據(jù)同步而不參與多數(shù)派投票的角色,將寫請(qǐng)求轉(zhuǎn)發(fā)到某一個(gè)區(qū)域(如圖2中的Region A),來避免直接多節(jié)點(diǎn)部署的投票延時(shí)問題。此種方式可以解決水平拓展問題和延時(shí)問題,但由于參與投票的角色都部署在一個(gè)地域內(nèi),當(dāng)此地域機(jī)房遇到災(zāi)難性時(shí)間時(shí),寫服務(wù)便不可用了。此種方式是Otter[3]所采用的部署方式。
多服務(wù)+Partition&單地域部署+Learner
圖3 多個(gè)服務(wù)處理分Partition
將數(shù)據(jù)按規(guī)則切分為不同Partition,每個(gè)地域一個(gè)Quorum提供服務(wù),不同地域Quorum負(fù)責(zé)不同Partition,地域之間Quorum使用Learner進(jìn)行不同Partition數(shù)據(jù)同步及寫請(qǐng)求轉(zhuǎn)發(fā),保證某區(qū)域出現(xiàn)問題只影響該區(qū)域Partition可用性。同時(shí)此種方案下會(huì)有正確性問題,即操作不符合順序一致性[4]的問題(見論文[1])。
實(shí)際實(shí)現(xiàn)時(shí)根據(jù)業(yè)務(wù)場(chǎng)景有各種解決方案,會(huì)針對(duì)性地進(jìn)行優(yōu)化和權(quán)衡,彌補(bǔ)缺陷。業(yè)界較常見方案的是單地域部署+Learner角色這種方案,通過同城多活和Learner做跨地域數(shù)據(jù)同步來保證較高的可用性和較高的效率。其他方案也各有優(yōu)化方案,跨地域部署可以通過減少達(dá)成決議時(shí)地域間通信,來減小延時(shí)和帶寬問題,如TiDB的Follower Replication[5];多服務(wù)+Partition&單地域部署+Learner這種方案的正確性也可以通過論文[1]中所述,在讀之前添加sync操作,犧牲一部分讀的可用性來保證一致性。
最后的結(jié)論如下表,后面會(huì)詳細(xì)闡釋其中的關(guān)鍵項(xiàng):
2 跨地域的權(quán)衡
通過第一部分總結(jié)的需求挑戰(zhàn)和前面對(duì)業(yè)界跨地域一致性系統(tǒng)解決方案的調(diào)研,可以總結(jié)出基于Paxos的分布式一致性系統(tǒng)在跨地域場(chǎng)景下的核心權(quán)衡點(diǎn):
- 寫操作跨地域走一致性協(xié)議達(dá)成決議太慢
- 地域內(nèi)多活無法提供極端情況下的可用性
- 需要具備分布式系統(tǒng)最核心的水平拓展能力
針對(duì)這三點(diǎn)問題,我們?cè)O(shè)計(jì)了一種日志鏡像解耦的跨地域一致性系統(tǒng)。
3 跨地域日志鏡像解耦
圖4 日志鏡像解耦示意圖
如圖3所示,我們的系統(tǒng)分為后端日志同步通道和前端全量狀態(tài)機(jī)——日志與鏡像解耦的架構(gòu)。后端跨地域全局日志同步通道,負(fù)責(zé)保證請(qǐng)求日志在各個(gè)區(qū)域的強(qiáng)一致性;前端全量狀態(tài)機(jī)部署在各地域內(nèi),處理客戶端請(qǐng)求,也負(fù)責(zé)與后端日志服務(wù)交互,對(duì)外提供全局強(qiáng)一致性元數(shù)據(jù)訪問服務(wù),接口可以根據(jù)業(yè)務(wù)需求快速修改狀態(tài)機(jī)來實(shí)現(xiàn)。
在全局日志與本地鏡像分離的架構(gòu)下,除了解耦本身帶來的系統(tǒng)運(yùn)維和可拓展性的提升,我們還可以解決很多未解耦架構(gòu)下的問題,后面幾條分析是在此種架構(gòu)下如何對(duì)之前思考部分幾大問題的一個(gè)解決:
寫操作效率
單從部署的模式上看,看起來與直接多地域多節(jié)點(diǎn)部署,然后各地域添加Learner角色的做法類似,是直接多節(jié)點(diǎn)部署和引入Learner的一個(gè)結(jié)合,綜合了兩種方式的優(yōu)缺點(diǎn)。最大區(qū)別在于,我們的日志和鏡像解耦了,也就是說跨地域的部分是足夠輕量高效的單純?nèi)罩就?,且由于每個(gè)地域只有一個(gè)節(jié)點(diǎn),能夠節(jié)省跨地域帶寬(類似TiDB的Follower Replication)。同時(shí)后端日志同步通道,也可以實(shí)現(xiàn)多Group的功能,將數(shù)據(jù)分成Partition,每個(gè)一致性Group負(fù)責(zé)不同的Partiton。
由于大部分業(yè)務(wù)場(chǎng)景的讀操作為讀本地?cái)?shù)據(jù),各種方式相差不大,主要進(jìn)行寫操作的延遲分析,下面是對(duì)于寫操作(或強(qiáng)一致性讀)的延遲分析:
RTT(Round-Trip Time),可以簡(jiǎn)單理解為發(fā)送消息方從發(fā)送請(qǐng)求到得到響應(yīng)所經(jīng)過的時(shí)間。由于跨地域網(wǎng)絡(luò)延遲較大,后面RTT主要指跨地域RTT。
(1)直接跨地域部署
對(duì)于一個(gè)常見的有主一致性協(xié)議,我們的請(qǐng)求分兩種情況:
訪問Leader所在地域 1個(gè)RTT(暫時(shí)忽略地域內(nèi)較小的延遲)
- Client -> Leader ----> Follower ----> Leader -> Client
訪問Follower所在地域 2個(gè)RTT
- Client -> Follower ----> Leader ----> Follower ----> Leader ----> Follower ->
(2)單地域部署+Learner同步
在地域內(nèi)多活,地域間Learnner同步的方案中,我們的延時(shí)為:
本地域 0個(gè)RTT
- Client -> Quorum -> Client
地域間 1個(gè)RTT
- Client -> Learner ----> Quorum ----> Learner -> Client
(3)多服務(wù)Partition,單地域部署+Learner同步(與B結(jié)果類似)
寫本地域Partition 0個(gè)RTT
跨Partition寫 1個(gè)RTT
(4)日志鏡像解耦的架構(gòu)(與A結(jié)果類似)
寫本地域Partiton 1個(gè)RTT
- Client ->Frontend -> LogChannel(local) ----> LogChannel (peer) ----> LogChannel (local) -> Frontend -> Client
跨Partition寫 2個(gè)RTT (Paxos兩階段提交/轉(zhuǎn)發(fā)leader)
- Client ->Frontend -> LogChannel (local) ----> LogChannel (peer) ----> LogChannel (local) ----> LogChannel (peer) ----> LogChannel (local) -> Frontend -> Client
經(jīng)過以上的對(duì)比,可以看出只要跨地域走一致性協(xié)議進(jìn)行寫操作,最少也會(huì)有1個(gè)RTT的延遲,而如果將Paxos Quorum只部署在單地域,又不能保證任何極端情況下的可用性。所以我們根據(jù)業(yè)務(wù)需要,可以進(jìn)行可用性和寫效率的權(quán)衡,日志鏡像解耦的架構(gòu)可以在多地域部署場(chǎng)景下保證極端的可用性和正確性,當(dāng)然效率上會(huì)比單地域部署+learner稍差一些,但如果采用多整體比直接多地域部署的方式要輕量高效,因?yàn)镼uorum規(guī)模不會(huì)因水平拓展增加,不會(huì)影響投票效率。與多服務(wù)分Partition部署的方案則沒有效率優(yōu)勢(shì),但在可運(yùn)維護(hù)性、正確性、可用性這些方面都有優(yōu)勢(shì)。
一致性
跨地域部署和單地域部署+Learner的強(qiáng)一致性是滿足的,zookeeper和etcd都有對(duì)應(yīng)的介紹,在此不做贅述。多服務(wù)Partition分Partion這種方案不滿足順序一致性,主要是因?yàn)槎喾?wù)不能保證每條寫操作commit的順序性,見下圖:
圖5 順序一致性
可以看到,當(dāng)兩個(gè)Client同時(shí)對(duì)x,y進(jìn)行修改時(shí),在寫操作并發(fā)程度較高的情況下,不能保證順序一致性。
順序一致性即可以將各個(gè)Client的操作排列出一個(gè)正確順序,在圖4的例子中:
- set1(x,5) => get1(y)->0 => set2(y,3) => get2(x)->5
或者
- set2(y,3) => get2(x)->0 => set2(y,3) => get1(y)->3
都是符合順序一致性的。
日志鏡像解耦的架構(gòu)的一致性可以簡(jiǎn)單理解為跨地域部署+Learner,寫操作有sync選項(xiàng),會(huì)在后端log提交成功并拉取到對(duì)應(yīng)log時(shí)才會(huì)返回成功,因此一定是可以拉取到其他Client在此操作之前的寫操作對(duì)應(yīng)的log,故符合順序一致性。
可用性
可用性這點(diǎn)與直接跨地域多節(jié)點(diǎn)部署的可用性類似,前端狀態(tài)機(jī)可以在某個(gè)地域后端節(jié)點(diǎn)掛掉情況下進(jìn)行請(qǐng)求轉(zhuǎn)發(fā),在后端全局日志服務(wù)不可用時(shí)也可以提供讀的可用性,可以提供極端情況下的讀寫高可用保證。
同時(shí)由于鏡像存儲(chǔ)在各個(gè)地域的狀態(tài)機(jī)中,當(dāng)某個(gè)前端狀態(tài)機(jī)掛掉時(shí)可以把客戶端切換到其他前端,failover恢復(fù)時(shí)也可以直接從后端拉取數(shù)據(jù)恢復(fù),在落后太多情況下才需要從本地域其他前端拉取鏡像,不用跨地域同步鏡像,由此可以使得前端的不可用時(shí)間極短。
水平拓展能力
水平拓展能力是分布式服務(wù)的核心能力,在前述的多種方案中,直接跨地域部署水平拓展能力極差,其他依賴Learner的方式,也解決了水平拓展的問題,只是解耦沒有日志鏡像解耦的設(shè)計(jì)干凈。
將以上幾個(gè)關(guān)鍵問題總結(jié)對(duì)比:
三 跨地域更多可能性
后端日志和前端鏡像解耦的狀態(tài)下,我們對(duì)跨地域場(chǎng)景的探索分為兩部分——后端日志同步輕量高效和前端狀態(tài)機(jī)靈活豐富。
- 輕量,體現(xiàn)在架構(gòu),后端只同步日志帶來的后端存儲(chǔ)壓力極小,只用同步輕量的增量日志。
- 高效,體現(xiàn)在后端的一致性協(xié)議,由于輕量,所以只需要考慮投票和選舉的邏輯,只用注重日志同步效率的提升,后端資源不用消耗在其他業(yè)務(wù)邏輯上。
- 靈活,體現(xiàn)在架構(gòu),前端可以自定義上傳日志,CAS、事務(wù)等都可以包裝成日志由前端解析和處理。
- 豐富,主要是體現(xiàn)在前端的狀態(tài)機(jī),由于日志的靈活留給我們探索和構(gòu)建的空間極大,可以根據(jù)需求包裝出處理各種復(fù)雜事務(wù)的狀態(tài)機(jī)。
新的架構(gòu)下有新的問題,這一部分主要探究如何吸取已有系統(tǒng)的優(yōu)點(diǎn),利用日志鏡像解耦下的輕量、靈活,來實(shí)現(xiàn)跨地域場(chǎng)景下一致性協(xié)議和狀態(tài)機(jī)的高效、豐富,也會(huì)對(duì)跨地域一致性系統(tǒng)后繼如何發(fā)展有一個(gè)思考和規(guī)劃??傮w目標(biāo)是后端一致性協(xié)議做精做深,前端狀態(tài)機(jī)做大做強(qiáng)。
1 高效的后端一致性協(xié)議
基于我們前面對(duì)寫操作效率的討論,在多地域?qū)懲粩?shù)據(jù)場(chǎng)景下,延遲只能控制在2RTT。因?yàn)榭绲赜驁?chǎng)景下,延遲占比主要在跨地域網(wǎng)絡(luò)通信,無論是有主的轉(zhuǎn)發(fā)還是無主的Paxos兩階段提交,延遲都有2RTT。但如果使用無主的協(xié)議,如Paxos的變種EPaxos[6],則可以盡可能提高跨地域場(chǎng)景下寫的效率,其延遲分Fast Path和Slow Path兩種情況,在Fast Path下延遲為1RTT, Slow Path下延遲為2RTT。
引用介紹EPaxos文章中的一句話:
若并發(fā)提議的日志之間沒有沖突,EPaxos只需要運(yùn)行PreAccept階段即可提交(Fast Path),否則需要運(yùn)行Accept階段才能提交(Slow Path)。
相比于分Partition操作,如果將后端一致性協(xié)議選為EPaxos,則可以保證極端情況下的可用性和大多數(shù)情況下延遲為1RTT,這是無主一致性協(xié)議在跨地域場(chǎng)景下的優(yōu)勢(shì),主要是因?yàn)槭∪チ艘淮无D(zhuǎn)發(fā)Leader操作的RTT。目前我們系統(tǒng)中使用的是最基礎(chǔ)的Paxos的實(shí)現(xiàn),在多地寫場(chǎng)景下延遲理論上與有主的協(xié)議相差不大,后繼發(fā)展期望利用EPaxos來加快跨地域場(chǎng)景下寫操作的效率。
由于不需要實(shí)現(xiàn)各種業(yè)務(wù)邏輯,高效便是后端一致性協(xié)議的最大訴求,當(dāng)然其正確性、穩(wěn)定性也是必不可少的,而對(duì)于前端的狀態(tài)機(jī),則有著豐富的場(chǎng)景來設(shè)計(jì)和發(fā)揮。
CAS操作
CAS操作在此種架構(gòu)下的實(shí)現(xiàn)是很自然的,由于后端只有一致性log,所以我們每一次CAS請(qǐng)求,自然而然會(huì)有Commit的先后順序,舉一個(gè)例子。
兩個(gè)客戶端同時(shí)寫同一個(gè)Key的值:
圖 6 CAS操作示意圖
開始時(shí)key的值為0,此時(shí)Client 1和Client 2并發(fā)對(duì)key進(jìn)行CAS操作,分別為CAS(key, 0, 1)和CAS(key, 0, 2),當(dāng)這兩個(gè)操作同時(shí)提交并Commit后,由于后端Quorum達(dá)成決議的先后,Replication Log一定會(huì)有先后順序,因此自然而然這兩個(gè)并發(fā)的CAS操作轉(zhuǎn)換為順序執(zhí)行。當(dāng)Frontend同步到這兩個(gè)操作的log時(shí),會(huì)依次apply這兩個(gè)操作到本地狀態(tài)機(jī),自然CAS(key, 0, 1)成功,更新key值為1,而CAS(key, 0, 2)更新失敗,這時(shí)前端會(huì)返回給對(duì)應(yīng)請(qǐng)求的Client其CAS請(qǐng)求是否成功或失敗的結(jié)果。
其原理是將一個(gè)并發(fā)操作變成了一個(gè)順序執(zhí)行的串行過程,由此避免了在跨地域場(chǎng)景下對(duì)加鎖的操作,可以想象如果是后端維護(hù)了一個(gè)kv結(jié)構(gòu)數(shù)據(jù),則還需要增加一個(gè)跨地域分布式鎖來完成此操作,相對(duì)更加繁瑣,效率也沒有保證。通過只同步日志把復(fù)雜計(jì)算轉(zhuǎn)移到Frontend,可以靈活地構(gòu)建前端狀態(tài)機(jī),更好地實(shí)現(xiàn)CAS或更復(fù)雜的事務(wù)功能(此種架構(gòu)可參考pravega的StateSynchronizer[7])。
Global ID
Global ID是一個(gè)常見的需求,分布式系統(tǒng)生成一個(gè)唯一ID,常見的有使用UUID、snow flake算法,或者基于數(shù)據(jù)庫、redis、zookeeper的方案。
類似使用zookeeper的znode數(shù)據(jù)版本進(jìn)行Global ID的生成,在此種日志鏡像分離架構(gòu)中,可以使用CAS接口調(diào)用,生成一個(gè)key作為Global ID,每次對(duì)Global ID進(jìn)行原子操作?;谏鲜龅腃AS設(shè)計(jì),跨地域并發(fā)場(chǎng)景下不需要加鎖,在使用方式上類似redis對(duì)key進(jìn)行原子操作。
2 Watch操作
訂閱功能是分布式協(xié)調(diào)服務(wù)的不可或缺的,是業(yè)務(wù)最常見的一種需求,下面是對(duì)zk和etcd的調(diào)研結(jié)果:
目前業(yè)界比較成熟的實(shí)現(xiàn)了訂閱通知的分布式協(xié)調(diào)系統(tǒng)包括ETCD和ZooKeeper,我們分別以這兩個(gè)系統(tǒng)為例講解各自的解決方案。
ETCD會(huì)保存數(shù)據(jù)的多個(gè)歷史版本(MVCC),通過單調(diào)遞增的版本號(hào)來表明版本的新舊,客戶端只要傳入自己關(guān)心的歷史版本,服務(wù)端就可以將后續(xù)的所有事件推送給客戶端。
Zookeeper并不會(huì)保存數(shù)據(jù)的多個(gè)歷史版本,只有當(dāng)前的數(shù)據(jù)狀態(tài),客戶端并不能訂閱數(shù)據(jù)的歷史版本,客戶端只能訂閱當(dāng)前狀態(tài)之后的改變事件,所以訂閱伴隨著讀,服務(wù)端把當(dāng)前的數(shù)據(jù)發(fā)送給客戶端,然后推送后續(xù)的事件,同時(shí)為了防止在failover等異常場(chǎng)景訂閱到老的數(shù)據(jù)和事件,客戶端會(huì)拒絕連接數(shù)據(jù)比較老的服務(wù)端(這依賴于服務(wù)端會(huì)在每個(gè)請(qǐng)求會(huì)返回當(dāng)前的服務(wù)端全局的XID)。
上述的調(diào)研結(jié)果中ETCD較為符合我們的接口設(shè)計(jì),目前ETCDv3 使用了HTTP/2的TCP鏈接多路復(fù)用,watch性能有提升。由于同為日志加狀態(tài)機(jī)結(jié)構(gòu),設(shè)計(jì)功能時(shí)主要參考了ETCD v3,借鑒其如何訂閱多個(gè)key以及返回全部歷史事件這兩個(gè)特性。若要達(dá)到etcd訂閱的功能,我們?cè)谇岸藸顟B(tài)機(jī)同步并解析日志時(shí),如果出現(xiàn)寫日志,則將kv結(jié)構(gòu)的狀態(tài)機(jī)Store和 專門提供給watch接口的狀態(tài)機(jī)watchableStore同時(shí)更新,具體實(shí)現(xiàn)可以完全參考etcd,然后按日志版本號(hào)將訂閱時(shí)版本后的歷史事件全部返回給客戶端。而訂閱多個(gè)key則同樣使用線段樹作為watcher的range keys存儲(chǔ)結(jié)構(gòu),可以實(shí)現(xiàn)watch范圍keys的watcher通知。
3 Lease機(jī)制
在無主的系統(tǒng)中實(shí)現(xiàn)高效的Lease機(jī)制是一大挑戰(zhàn),無主的系統(tǒng)中沒有Leader,任意節(jié)點(diǎn)均可維護(hù)Lease,Lease分布在各個(gè)節(jié)點(diǎn)上,當(dāng)有節(jié)點(diǎn)不可用時(shí),需要平滑切換到其它節(jié)點(diǎn)。無主的系統(tǒng)中實(shí)現(xiàn)高效的Lease機(jī)制的難點(diǎn)在于隨著Lease數(shù)量的增加,如何避免后端的一致性協(xié)議中出現(xiàn)大量的Lease維持消息,影響系統(tǒng)性能,最好讓Lease維持消息能夠直接在前端本地處理,而不經(jīng)過后端。所以我們的思路是將客戶端與前端的Lease聚合到前端與后端的Lease,使得Lease維持消息能夠直接在前端本地處理。
四 結(jié)語
隨著全球化戰(zhàn)略的推進(jìn),跨地域方面的需求一定會(huì)越來越迫切,跨地域場(chǎng)景的真正痛點(diǎn)也會(huì)越來越清晰,希望我們?cè)诳绲赜蚍矫娴恼{(diào)研和探索可以給大家一個(gè)思路和參考,我們也會(huì)繼續(xù)探索跨地域日志鏡像分離的架構(gòu)下更多的可能性。
相關(guān)鏈接
[1]https://www.usenix.org/conference/atc16/technical-sessions/presentation/lev-ari
[2]https://github.com/etcd-io/etcd/blob/master/Documentation/learning/design-learner.md
[3]https://github.com/alibaba/otter
[4]https://zhuanlan.zhihu.com/p/43949695
[5]https://zhuanlan.zhihu.com/p/94663335
[6]https://zhuanlan.zhihu.com/p/163271175
[7]https://github.com/pravega/pravega/blob/master/documentation/src/docs/state-synchronizer-design.md