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