分布式系统搭建:服务发现揭秘
CAP理論
加州大學(xué)終身教授與著名計(jì)算機(jī)科學(xué)家Eric Allen Brewer在90年代末提出了CAP理論,理論斷言任一個(gè)基于網(wǎng)絡(luò)的分布式系統(tǒng),最多只能滿足“數(shù)據(jù)一致性”、“可用性”、“分區(qū)容錯(cuò)性”三要素中的兩個(gè)要素。
該理論后被MIT證明可行,故架構(gòu)師無(wú)需將精力浪費(fèi)在如何設(shè)計(jì)能滿足三者的完美分布式系統(tǒng),而是應(yīng)該進(jìn)行取舍。
?
CAP理論也即被捧為“分布式系統(tǒng)設(shè)計(jì)”的重要評(píng)分標(biāo)準(zhǔn),其包含下述三項(xiàng)定義:
?
Consistency(一致性):集群中所有節(jié)點(diǎn)在同一時(shí)刻可見(jiàn)同樣的值。
Availability(可用性):健康的節(jié)點(diǎn)在限時(shí)內(nèi),可返回可靠的結(jié)果。
Partition tolerance(分區(qū)容錯(cuò)性):集群中某些節(jié)點(diǎn)失聯(lián)后,集群仍可繼續(xù)服務(wù)。
?
那為什么一個(gè)系統(tǒng)只能同時(shí)滿足三要素中的兩個(gè)要素呢?我們來(lái)看看下面例子:
?
1.首先使分布式系統(tǒng)滿足“分區(qū)容錯(cuò)性”要素:
當(dāng)上海、臺(tái)北服務(wù)器共用數(shù)據(jù)存儲(chǔ)時(shí),上海數(shù)據(jù)中心存儲(chǔ)的宕機(jī)將造成臺(tái)北服務(wù)器也不可用,拓?fù)鋱D如下。
?
如何來(lái)滿足分區(qū)容錯(cuò)性:我們可在各數(shù)據(jù)中心分別建存儲(chǔ)機(jī)制,在各數(shù)據(jù)中心存儲(chǔ)進(jìn)行寫操作的同時(shí),觸發(fā)存儲(chǔ)同步,保障數(shù)據(jù)中心間存儲(chǔ)數(shù)據(jù)同步。
故當(dāng)任一數(shù)據(jù)中心存儲(chǔ)宕機(jī),也不會(huì)造成其它數(shù)據(jù)中心的存儲(chǔ)讀寫操作,如下圖所示:
?
2.滿足“分區(qū)容錯(cuò)性”的前提下,“一致性”,“可用性”兩者只可選其一假定當(dāng)前兩地存儲(chǔ)中的數(shù)據(jù)為“版本1”,此時(shí)上海與臺(tái)北數(shù)據(jù)中心網(wǎng)絡(luò)中斷,存儲(chǔ)間無(wú)法同步。然后上海服務(wù)器將數(shù)據(jù)版本更新為“版本2”,由于同步受阻,臺(tái)北數(shù)據(jù)中心仍保存數(shù)據(jù)版本“版本1”,如下圖所示:
?
“臺(tái)北服務(wù)器向臺(tái)北分區(qū)存儲(chǔ)進(jìn)行查詢”這一動(dòng)作在CAP理論模型下只能滿足下述情況之一
?
(CP)保障“一致性”,放棄“可用性”:
等待網(wǎng)絡(luò)恢復(fù)正常,上海存儲(chǔ)將“版本2”同步至臺(tái)北存儲(chǔ),臺(tái)北存儲(chǔ)將滿足“一致性”的數(shù)據(jù)“版本2”返回給服務(wù)器。
由于網(wǎng)絡(luò)恢復(fù)時(shí)間的不確定性,請(qǐng)求可能會(huì)超時(shí),違反“可用性”限時(shí)的條件。
(AP)保障“可用性”,放棄“一致性”:
臺(tái)北存儲(chǔ)在“可用性”高響應(yīng)的驅(qū)動(dòng)下將過(guò)期數(shù)據(jù)“版本1”返回給服務(wù)器。
由于返回的“版本1”與最新數(shù)據(jù)“版本2”不一致,違反了“一致性”。
?
CAP理論小結(jié):
無(wú)論CP,AP還是CA,在CAP理論驅(qū)動(dòng)下的系統(tǒng),都以SLA(Service Level Agreement)為系統(tǒng)最終評(píng)估基準(zhǔn)。目前SLA 5個(gè)9乃至6個(gè)9的系統(tǒng),都會(huì)以AP設(shè)計(jì)為重,略微放棄一致性來(lái)?yè)Q取系統(tǒng)的“活”。
?
目前主流的分布式系統(tǒng)設(shè)計(jì)理論BASE(Basically Available?基本可用)(Soft State?軟狀態(tài))(Eventual Consistency?最終一致性)則是對(duì)CAP中AP理論的擴(kuò)展,通過(guò)實(shí)現(xiàn)“最終一致性”來(lái)保障SLA的同時(shí)確保信息準(zhǔn)確。
基于BASE理論設(shè)計(jì)的主要的產(chǎn)品則為主流NoSQL數(shù)據(jù)庫(kù):包括Cassandra,MongoDB,Redis, CouchDB等。
?
故在AP模型穩(wěn)定的情況下,SLA指標(biāo)中能有幾個(gè)9,與Consistency(一致性)的算法實(shí)現(xiàn)密切相關(guān),下面我們來(lái)看一下“一致性算法”
一致性算法Raft
20世紀(jì)80年代開(kāi)始,一致性算法的研究就沒(méi)有停止過(guò),主流的實(shí)現(xiàn)則依賴共享內(nèi)存(Shared memory)和消息傳遞(Messages passing)。直至21世紀(jì)的今天,基于“消息傳遞”為一致性算法實(shí)現(xiàn)的系統(tǒng)占到了絕大多數(shù)。
?
微軟研究院首席科學(xué)家、2013年圖林獎(jiǎng)獲得者LeslieLamport于1990年提出的一種基于消息傳遞且具有高度容錯(cuò)特性的一致性算法Paxos。該算法的典型應(yīng)用場(chǎng)景為分布式數(shù)據(jù)庫(kù):在一個(gè)多節(jié)點(diǎn)的分布式系統(tǒng)中,“使用一致性算法”保證每個(gè)節(jié)點(diǎn)執(zhí)行相同的命令序列,確保每個(gè)節(jié)點(diǎn)的狀態(tài)一致。
?
Google的分布式鎖服務(wù)Chubby,Apache的分布式服務(wù)框架ZooKeeper都是基于Paxos算法進(jìn)行的實(shí)現(xiàn)。Paxos也是類似算法中最為可靠與廣知的,但Paxos算法的流程復(fù)雜與實(shí)現(xiàn)困難導(dǎo)致世界級(jí)產(chǎn)品數(shù)量極少。
?
2013年來(lái)自Stanford大學(xué)的DiegoOngaro、John Ousterhout發(fā)布論文“In Search of an Understandable Consensus Algorithm”,公布了的新的分布式協(xié)議研究稱為Raft,它是一個(gè)為真實(shí)世界應(yīng)用建立的協(xié)議,主要注重協(xié)議的落地性和可理解性。
?
時(shí)至今日,Raft的易實(shí)現(xiàn)性使其成為與Paxos同級(jí)別的一致性算法,在Raft的Github官網(wǎng)上,已發(fā)布了十多種Raft一致性算法的實(shí)現(xiàn),生態(tài)圈日漸強(qiáng)大。詳細(xì)信息可見(jiàn):https://raft.github.io/
主流的服務(wù)發(fā)現(xiàn)框架Etcd,Consul等都是基于Raft一致性算法實(shí)現(xiàn)的。Google開(kāi)源的容器集群管理Kubernetes作為Docker生態(tài)圈中重要一員,也是基于Raft來(lái)管理一致性的。
?
Raft算法拆解后主要包含三大功能,各功能運(yùn)作的完整流程也可參考Raft可視化網(wǎng)站,讓我們通過(guò)生動(dòng)的圖形來(lái)了解Raft算法的秘密吧!
網(wǎng)址:
http://thesecretlivesofdata.com/raft/
?
1.???????Leader選取:
Raft服務(wù)集群中有3個(gè)角色Leader,Candidate與Follower。Leader則會(huì)統(tǒng)一管理Follower與自己的狀態(tài)機(jī)同步。
?
Raft使用心跳機(jī)制來(lái)觸發(fā)選舉Leader。在沒(méi)有Leader的情況下在Follower默認(rèn)的“選舉計(jì)時(shí)器”(150毫秒到300毫秒超時(shí))超時(shí)后,將會(huì)推舉自己為Candidate,當(dāng)大多數(shù)(n/2+1?)節(jié)點(diǎn)同意后將會(huì)升級(jí)為Leader。然后Leader與Follower間使用心跳進(jìn)行狀態(tài)維護(hù),只要心跳是在“心跳計(jì)時(shí)器”超時(shí)范圍內(nèi),Leader狀態(tài)則可永久保持。
?
在Raft算法內(nèi),只會(huì)存在一個(gè)Leader與多個(gè)Follower,集群維護(hù)單個(gè)數(shù)服務(wù)器。
?
*在極端多Follower“選舉計(jì)時(shí)器”同時(shí)超時(shí),多Candidate同時(shí)出現(xiàn)的情況下,則以收到其他Follower推舉回應(yīng)同時(shí)重置“選舉計(jì)時(shí)器”的時(shí)間點(diǎn)來(lái)決定最終Leader。
?
Leader選舉的流程如下,圖來(lái)自Stanford論文:
?
2.???????日志復(fù)制、同步:
Leader角色負(fù)責(zé)日志同步,流程如下:
當(dāng)Leader收到客戶端信息,則先寫入本地日志文件,同時(shí)將信息發(fā)給其他Follower。當(dāng)大多數(shù)Follower保存至本地成功,則回復(fù)Leader成功,Leader獲取大多數(shù)Follower回復(fù)后,提交本地寫入的日志,并則通知客戶端收到信息。
?
如Follower有丟包或者奔潰,Leader將進(jìn)行重試來(lái)保障一致性。所以數(shù)據(jù)的最終提交、狀態(tài)機(jī)的維護(hù)將由Leader決定。Leader會(huì)保障多數(shù)節(jié)點(diǎn)寫入信息來(lái)進(jìn)行最終提交。
?
如下圖所示,Leader上最后寫入的x<-4未被提交,則是由于僅有Leader與1/4的Follower,共2/5的節(jié)點(diǎn)寫入此日志。而x<-5則有Leader與1/2的Follower,共3/5 (n/2+1)節(jié)點(diǎn)寫入此日志,Leader發(fā)現(xiàn)大多數(shù)節(jié)點(diǎn)3/5已寫入信息成功,做了最終提交。
?
?
3.???????安全性:
Leader作為Raft集群的控制核心,也存在奔潰的可能。此時(shí)則集群中任意Follower可推舉自己為Candidate。Raft的安全性保障當(dāng)Follower如沒(méi)有獲得當(dāng)前完整Committed entries(見(jiàn)上圖)時(shí),則無(wú)法成為Candidate。此安全性舉動(dòng)保障了數(shù)據(jù)的可靠性,不會(huì)丟數(shù)據(jù)。
?
如要保障新選舉的Leader不會(huì)將過(guò)期臟數(shù)據(jù)同步至Follower。安全性檢查會(huì)在做數(shù)據(jù)的提交時(shí),也檢查當(dāng)前Leader所要提交的數(shù)據(jù)至少有一個(gè)存儲(chǔ)在大部分Follower上。
?
當(dāng)新Leader在工作的同時(shí),老Leader突然恢復(fù)工作。Raft的安全性保障使用Term號(hào)的方式使老Leader發(fā)出的過(guò)期Term號(hào)對(duì)所有Follower都不生效。保障了老Leader不會(huì)觸發(fā)錯(cuò)誤同步,直至降級(jí)為Follower。
?
Raft一致性算法小結(jié):
Raft通過(guò)算法實(shí)現(xiàn)強(qiáng)一致性。但是其單一Leader節(jié)點(diǎn)的設(shè)計(jì)在寫操作量大的情況下會(huì)造成單點(diǎn)寫瓶頸。故使用場(chǎng)景為讀操作大于寫操作的,對(duì)一致性要求高的系統(tǒng)。
?
服務(wù)發(fā)現(xiàn)框架Consul介紹
Consul為Hashicorp公司使用Go語(yǔ)言編寫的開(kāi)源項(xiàng)目,其核心是基于Raft(CAP一致性算法)與Gossip(BASE最終一致性算法)進(jìn)行實(shí)現(xiàn)的。基于Raft與Gossip的Consul集群,可保障Consul Server集群(服務(wù)端)間的數(shù)據(jù)一致性同步,Consul Server集群與集群間、Consul Agent(客戶端)與Agent間的數(shù)據(jù)最終一致性同步。
?
*Gossip最終一致性算法嘗試解決的問(wèn)題是:在一個(gè)有界網(wǎng)絡(luò)中,每個(gè)節(jié)點(diǎn)都隨機(jī)地與其他節(jié)點(diǎn)通信,經(jīng)過(guò)一番雜亂無(wú)章的通信,最終所有節(jié)點(diǎn)的狀態(tài)都會(huì)達(dá)成一致。Gossip具有“去中心化的特點(diǎn)”,也天然具有分布式容錯(cuò),雖然無(wú)法保證在某個(gè)時(shí)刻所有節(jié)點(diǎn)狀態(tài)一致,但可以保證在”最終“所有節(jié)點(diǎn)一致。
?
Consul的特色非常適合融入當(dāng)前互聯(lián)網(wǎng)公司的微服務(wù)架構(gòu),可輕松覆蓋多種操作系統(tǒng)。官方已經(jīng)發(fā)布的Consul客戶端支持Mac OS X、FreeBSD、Linux、Solaris、Windows等多種操作系統(tǒng),發(fā)布在這些操作系統(tǒng)上的Restful API都可輕松接入Consul集群。
?
Consul產(chǎn)品開(kāi)源的同時(shí)也提供了多種語(yǔ)言的接入SDK,包括Go,Python,Php,Scala,Java,ErLang,Ruby,Node.js,.NET,Perl等,大大降低了開(kāi)發(fā)人員的接入工時(shí)。
?
下圖為Consul在多數(shù)據(jù)中心部署的架構(gòu)圖,單數(shù)據(jù)中心內(nèi)使用Raft算法保障服務(wù)端一致性,同時(shí)使用Gossip協(xié)議進(jìn)行跨數(shù)據(jù)中心(WAN Gossip)同步,與客戶端間(LAN Gossip)同步。
兩種一致性算法結(jié)合使用的Consul集群可保證各個(gè)節(jié)點(diǎn)的數(shù)據(jù)一致。
?
.NET API服務(wù)如何接入Consul服務(wù)發(fā)現(xiàn)框架
首先將Consul以服務(wù)端模式部署在至少3臺(tái)(總臺(tái)數(shù)為單數(shù))服務(wù)器上,然后在.NET API部署服務(wù)器上安裝Consul Agent模式。
由于.NET API多運(yùn)行于Windows服務(wù)器上,可使用nssm.exe(http://www.nssm.cc/)來(lái)進(jìn)行從命令行至windows服務(wù)的包裝,保障跨Windows會(huì)話的安全性。
?
服務(wù)端啟動(dòng)腳本,需使用-ui-dir來(lái)指定UI項(xiàng)目路徑
Consul ?agent -server -bootstrap-expect 2 -data-dir ?D:\TGOP\ServiceDiscovery\ConsulData -node=TGOP-Consul-Server1 -bind=172.16.11.211 ?-dc=Shanghai-DC1 -client=172.16.11.211 -ui-dir=./UI |
?
Agent端啟動(dòng)腳本僅需加入指定Consul服務(wù)端集群
Consul ?agent -data-dir D:\TGOP\ServiceDiscovery\ConsulData ?-node=TGOP-Consul-Agent-LucasPC -bind=127.0.0.1 -dc=Shanghai-DC1 -client=127.0.0.1 ?-join tgop-apistore.vipabc.com |
?
Consul服務(wù)端與Agent端啟動(dòng)后,可通過(guò)http://consulserver:8500/ui?地址進(jìn)行Consul集群健康狀態(tài)管理。
?
.NET API服務(wù)發(fā)布與發(fā)現(xiàn)的SDK接入方法:
?
通過(guò)Nuget包管理器還原并安裝Consul.NET SDK安裝包,當(dāng)前版本為7.0.5。使用SDK安裝包中提供的ConsulClient.Agent.ServiceRegister方法進(jìn)行“服務(wù)注冊(cè)”,可使用的默認(rèn)Agent地址為http://127.0.0.1:8500/?核心方法如下
Task<WriteResult> ?ServiceRegister(AgentServiceRegistration?service,?CancellationToken ?ct =?null); |
?
使用ConsulClient.Agent. ServiceDeregister方法進(jìn)行“服務(wù)注銷”
Task<WriteResult> ServiceDeregister(string?serviceID,?CancellationToken?ct =?null); |
?
使用ConsulClient.Health.Service方法進(jìn)行“服務(wù)發(fā)現(xiàn)”,將會(huì)返回符合要求的服務(wù)列表,后通過(guò)主流負(fù)載均衡算法進(jìn)行最終服務(wù)篩選,完成服務(wù)發(fā)現(xiàn)流程。
Task<QueryResult<ServiceEntry[]>> Service(string??service,?string?tag,?bool?passingOnly,?CancellationToken?ct =?null); |
?
在.NET API啟動(dòng)與退出時(shí)集成Consul.NET SDK相應(yīng)的注冊(cè)與注銷方法,完成服務(wù)自注冊(cè)。在.NET API需要與其他API進(jìn)行通訊時(shí),使用服務(wù)發(fā)現(xiàn)方法完成地址查詢,后發(fā)起Restful HTTP請(qǐng)求完成API調(diào)用。
進(jìn)行服務(wù)注冊(cè)時(shí),需通過(guò)AgentServiceRegistration.AgentServiceCheck類型將心跳HTTP的接口信息,心跳間隔信息等同時(shí)遞交注冊(cè),ConsulAgent將會(huì)以配置好的間隔對(duì)服務(wù)進(jìn)行心跳檢查,來(lái)保障任意Agent進(jìn)行“服務(wù)發(fā)現(xiàn)”時(shí),獲取的注冊(cè)API為可用的。
?
Consul服務(wù)發(fā)現(xiàn)框架集成小結(jié):
在Consul集群基礎(chǔ)設(shè)施部署完畢,相應(yīng)SDK語(yǔ)言包成熟的基礎(chǔ)上,用戶開(kāi)發(fā)的Restful API可輕松接入集群。Consul的核心架構(gòu)于一致性算法的基石上,各服務(wù)節(jié)點(diǎn)的信息可靠性、可用性得到高保障,服務(wù)與服務(wù)之間可無(wú)障礙進(jìn)行溝通,形成微服務(wù)網(wǎng)。
?
參考文獻(xiàn):
https://en.wikipedia.org/wiki/Eric_Brewer_(scientist)
https://en.wikipedia.org/wiki/CAP_theorem
http://www.julianbrowne.com/article/viewer/brewers-cap-theorem
https://en.wikipedia.org/wiki/Raft_(computer_science)
https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf
https://en.wikipedia.org/wiki/Paxos_(computer_science)
https://en.wikipedia.org/wiki/Gossip
https://raft.github.io/
http://thesecretlivesofdata.com/raft/
https://www.consul.io/docs/internals/architecture.html
https://www.nuget.org/packages/Consul
相關(guān)文章:?
Consul入門
使用C# 和Consul進(jìn)行分布式系統(tǒng)協(xié)調(diào)
Consul 服務(wù)注冊(cè)與服務(wù)發(fā)現(xiàn)
搭建consul 集群
原文地址:http://www.rcgus.com/gyys377188451/2352438.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的分布式系统搭建:服务发现揭秘的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 又踩.NET Core的坑:在同步方法中
- 下一篇: 在ASP.NET Core Web AP