干掉 "ZooKeeper"?阿里為什么不用ZK做服務(wù)發(fā)現(xiàn)?
站在未來的路口,回望歷史的迷途,常常會很有意思,因?yàn)槲覀儠唤?jīng)意地興起瘋狂的念頭,例如如果當(dāng)年某事提前發(fā)生了,而另外一件事又沒有發(fā)生會怎樣?一如當(dāng)年的奧匈帝國皇位繼承人斐迪南大公夫婦如果沒有被塞爾維亞族熱血青年普林西普槍殺會怎樣,又如若當(dāng)年的丘老道沒有經(jīng)過牛家村會怎樣?
2007年底,淘寶開啟一個(gè)叫做“五彩石”的內(nèi)部重構(gòu)項(xiàng)目,這個(gè)項(xiàng)目后來成為了淘寶服務(wù)化、面向分布式走自研之路,走出了互聯(lián)網(wǎng)中間件體系之始,而淘寶服務(wù)注冊中心ConfigServer于同年誕生。
2008年前后,Yahoo 這個(gè)曾經(jīng)的互聯(lián)網(wǎng)巨頭開始逐漸在公開場合宣講自己的大數(shù)據(jù)分布式協(xié)調(diào)產(chǎn)品 ZooKeeper,這個(gè)產(chǎn)品參考了Google 發(fā)表的關(guān)于Chubby以及 Paxos 的論文。
2010年11月,ZooKeeper從 Apache Hadoop的子項(xiàng)目發(fā)展為 Apache的頂級項(xiàng)目,正式宣告 ZooKeeper成為一個(gè)工業(yè)級的成熟穩(wěn)定的產(chǎn)品。
2011年,阿里巴巴開源Dubbo,為了更好開源,需要?jiǎng)冸x與阿里內(nèi)部系統(tǒng)的關(guān)系,Dubbo 支持了開源的 ZooKeeper 作為其注冊中心,后來在國內(nèi),在業(yè)界諸君的努力實(shí)踐下,Dubbo + ZooKeeper 的典型的服務(wù)化方案成就了 ZooKeeper 作為注冊中心的聲名。
2015年雙11,ConfigServer 服務(wù)內(nèi)部近8個(gè)年頭過去了,阿里巴巴內(nèi)部“服務(wù)規(guī)?!背瑤装偃f ,以及推進(jìn)“千里之外”的IDC容災(zāi)技術(shù)戰(zhàn)略等,共同促使阿里巴巴內(nèi)部開啟了 ConfigServer 2.0 到 ConfigServer 3.0 的架構(gòu)升級之路。
時(shí)間走向2018年,站在10年的時(shí)間路口上,有多少人愿意在追逐日新月異的新潮技術(shù)概念的時(shí)候,稍微慢一下腳步,仔細(xì)凝視一下服務(wù)發(fā)現(xiàn)這個(gè)領(lǐng)域,有多少人想到過或者思考過一個(gè)問題:
服務(wù)發(fā)現(xiàn),ZooKeeper 真的是最佳選擇么?
而回望歷史,我們也偶有迷思,在服務(wù)發(fā)現(xiàn)這個(gè)場景下,如果當(dāng)年 ZooKeeper 的誕生之日比我們 HSF 的注冊中心 ConfigServer 早一點(diǎn)會怎樣?
我們會不會走向先使用ZooKeeper然后瘋狂改造與修補(bǔ)ZooKeeper以適應(yīng)阿里巴巴的服務(wù)化場景與需求的彎路?
但是,站在今天和前人的肩膀上,我們從未如今天這樣堅(jiān)定的認(rèn)知到,在服務(wù)發(fā)現(xiàn)領(lǐng)域,ZooKeeper 根本就不能算是最佳的選擇,一如這些年一直與我們同行的Eureka以及這篇文章 Eureka! Why You Shouldn’t Use ZooKeeper for Service Discovery 那堅(jiān)定的闡述一樣,為什么你不應(yīng)該用 ZooKeeper 做服務(wù)發(fā)現(xiàn)!
吾道不孤矣。
注冊中心需求分析及關(guān)鍵設(shè)計(jì)考量
接下來,讓我們回歸對服務(wù)發(fā)現(xiàn)的需求分析,結(jié)合阿里巴巴在關(guān)鍵場景上的實(shí)踐,來一一分析,一起探討為何說 ZooKeeper 并不是最合適的注冊中心解決方案。
注冊中心是 CP 還是 AP 系統(tǒng)?
CAP 和 BASE 理論相信讀者都已經(jīng)耳熟能詳,其業(yè)已成了指導(dǎo)分布式系統(tǒng)及互聯(lián)網(wǎng)應(yīng)用構(gòu)建的關(guān)鍵原則之一,在此不再贅述其理論,我們直接進(jìn)入對注冊中心的數(shù)據(jù)一致性和可用性需求的分析:
- 數(shù)據(jù)一致性需求分析
注冊中心最本質(zhì)的功能可以看成是一個(gè)Query函數(shù)Si = F(service-name),以service-name為查詢參數(shù),service-name對應(yīng)的服務(wù)的可用的endpoints (ip:port)列表為返回值.
注: 后文將 service 簡寫為 svc。
先來看看關(guān)鍵數(shù)據(jù)endpoints (ip:port)不一致性帶來的影響,即 CAP 中的 C 不滿足帶來的后果 :
如上圖所示,如果一個(gè) svcB 部署了10個(gè)節(jié)點(diǎn) (副本/Replica),如果對于同一個(gè)服務(wù)名 svcB, 調(diào)用者 svcA 的2個(gè)節(jié)點(diǎn)的2次查詢返回了不一致的數(shù)據(jù),例如: S1 = { ip1,ip2,ip3...,ip9 }, S2 = { ip2,ip3,....ip10 }, 那么這次不一致帶來的影響是什么?
相信你一定已經(jīng)看出來了,svcB 的各個(gè)節(jié)點(diǎn)流量會有一點(diǎn)不均衡。
ip1和ip10相對其它8個(gè)節(jié)點(diǎn){ip2...ip9},請求流量小了一點(diǎn),但很明顯,在分布式系統(tǒng)中,即使是對等部署的服務(wù),因?yàn)檎埱蟮竭_(dá)的時(shí)間,硬件的狀態(tài),操作系統(tǒng)的調(diào)度,虛擬機(jī)的 GC 等,任何一個(gè)時(shí)間點(diǎn),這些對等部署的節(jié)點(diǎn)狀態(tài)也不可能完全一致,而流量不一致的情況下,只要注冊中心在SLA承諾的時(shí)間內(nèi)(例如1s內(nèi))將數(shù)據(jù)收斂到一致狀態(tài)(即滿足最終一致),流量將很快趨于統(tǒng)計(jì)學(xué)意義上的一致,所以注冊中心以最終一致的模型設(shè)計(jì)在生產(chǎn)實(shí)踐中完全可以接受。
- 分區(qū)容忍及可用性需求分析
接下來我們看一下網(wǎng)絡(luò)分區(qū)(Network Partition)情況下注冊中心不可用對服務(wù)調(diào)用產(chǎn)生的影響,即 CAP 中的A不滿足時(shí)帶來的影響。
考慮一個(gè)典型的ZooKeeper三機(jī)房容災(zāi)5節(jié)點(diǎn)部署結(jié)構(gòu) (即2-2-1結(jié)構(gòu)),如下圖:
當(dāng)機(jī)房3出現(xiàn)網(wǎng)絡(luò)分區(qū)(Network Partitioned)的時(shí)候,即機(jī)房3在網(wǎng)絡(luò)上成了孤島,我們知道雖然整體 ZooKeeper 服務(wù)是可用的,但是節(jié)點(diǎn)ZK5是不可寫的,因?yàn)槁?lián)系不上 Leader。
也就是說,這時(shí)候機(jī)房3的應(yīng)用服務(wù) svcB 是不可以新部署,重新啟動(dòng),擴(kuò)容或者縮容的,但是站在網(wǎng)絡(luò)和服務(wù)調(diào)用的角度看,機(jī)房3的 svcA 雖然無法調(diào)用機(jī)房1和機(jī)房2的 svcB,但是與機(jī)房3的svcB之間的網(wǎng)絡(luò)明明是 OK 的啊,為什么不讓我調(diào)用本機(jī)房的服務(wù)?
現(xiàn)在因?yàn)樽灾行淖陨頌榱吮DX裂(P)下的數(shù)據(jù)一致性(C)而放棄了可用性,導(dǎo)致了同機(jī)房的服務(wù)之間出現(xiàn)了無法調(diào)用,這是絕對不允許的!可以說在實(shí)踐中,注冊中心不能因?yàn)樽陨淼娜魏卧蚱茐姆?wù)之間本身的可連通性,這是注冊中心設(shè)計(jì)應(yīng)該遵循的鐵律! 后面在注冊中心客戶端災(zāi)容上我們還會繼續(xù)討論。
同時(shí)我們再考慮一下這種情況下的數(shù)據(jù)不一致性,如果機(jī)房1,2,3之間都成了孤島,那么如果每個(gè)機(jī)房的svcA都只拿到本機(jī)房的 svcB 的ip列表,也即在各機(jī)房svcB 的ip列表數(shù)據(jù)完全不一致,影響是什么?
其實(shí)沒啥大影響,只是這種情況下,全都變成了同機(jī)房調(diào)用,我們在設(shè)計(jì)注冊中心的時(shí)候,有時(shí)候甚至?xí)鲃?dòng)利用這種注冊中心的數(shù)據(jù)可以不一致性,來幫助應(yīng)用主動(dòng)做到同機(jī)房調(diào)用,從而優(yōu)化服務(wù)調(diào)用鏈路 RT 的效果!
通過以上我們的闡述可以看到,在 CAP 的權(quán)衡中,注冊中心的可用性比數(shù)據(jù)強(qiáng)一致性更寶貴,所以整體設(shè)計(jì)更應(yīng)該偏向 AP,而非 CP,數(shù)據(jù)不一致在可接受范圍,而P下舍棄A卻完全違反了注冊中心不能因?yàn)樽陨淼娜魏卧蚱茐姆?wù)本身的可連通性的原則。
服務(wù)規(guī)模、容量、服務(wù)聯(lián)通性
你所在公司的“微服務(wù)”規(guī)模有多大?數(shù)百微服務(wù)?部署了上百個(gè)節(jié)點(diǎn)?那么3年后呢?互聯(lián)網(wǎng)是產(chǎn)生奇跡的地方,也許你的“服務(wù)”一夜之間就家喻戶曉,流量倍增,規(guī)模翻番!
當(dāng)數(shù)據(jù)中心服務(wù)規(guī)模超過一定數(shù)量 (服務(wù)規(guī)模=F{服務(wù)pub數(shù),服務(wù)sub數(shù)}),作為注冊中心的 ZooKeeper 很快就會像下圖的驢子一樣不堪重負(fù)
其實(shí)當(dāng)ZooKeeper用對地方時(shí),即用在粗粒度分布式鎖,分布式協(xié)調(diào)場景下,ZooKeeper 能支持的tps 和支撐的連接數(shù)是足夠用的,因?yàn)檫@些場景對于 ZooKeeper 的擴(kuò)展性和容量訴求不是很強(qiáng)烈。
但在服務(wù)發(fā)現(xiàn)和健康監(jiān)測場景下,隨著服務(wù)規(guī)模的增大,無論是應(yīng)用頻繁發(fā)布時(shí)的服務(wù)注冊帶來的寫請求,還是刷毫秒級的服務(wù)健康狀態(tài)帶來的寫請求,還是恨不能整個(gè)數(shù)據(jù)中心的機(jī)器或者容器皆與注冊中心有長連接帶來的連接壓力上,ZooKeeper 很快就會力不從心,而 ZooKeeper 的寫并不是可擴(kuò)展的,不可以通過加節(jié)點(diǎn)解決水平擴(kuò)展性問題。
要想在 ZooKeeper 基礎(chǔ)上硬著頭皮解決服務(wù)規(guī)模的增長問題,一個(gè)實(shí)踐中可以考慮的方法是想辦法梳理業(yè)務(wù),垂直劃分業(yè)務(wù)域,將其劃分到多個(gè) ZooKeeper 注冊中心,但是作為提供通用服務(wù)的平臺機(jī)構(gòu)組,因自己提供的服務(wù)能力不足要業(yè)務(wù)按照技術(shù)的指揮棒配合劃分治理業(yè)務(wù),真的可行么?
而且這又違反了因?yàn)樽灾行淖陨淼脑颍芰Σ蛔悖┢茐牧朔?wù)的可連通性,舉個(gè)簡單的例子,1個(gè)搜索業(yè)務(wù),1個(gè)地圖業(yè)務(wù),1個(gè)大文娛業(yè)務(wù),1個(gè)游戲業(yè)務(wù),他們之間的服務(wù)就應(yīng)該老死不相往來么?也許今天是肯定的,那么明天呢,1年后呢,10年后呢?誰知道未來會要打通幾個(gè)業(yè)務(wù)域去做什么奇葩的業(yè)務(wù)創(chuàng)新?注冊中心作為基礎(chǔ)服務(wù),無法預(yù)料未來的時(shí)候當(dāng)然不能妨礙業(yè)務(wù)服務(wù)對未來固有聯(lián)通性的需求。
注冊中心需要持久存儲和事務(wù)日志么?
需要,也不需要。
我們知道 ZooKeeper 的 ZAB 協(xié)議對每一個(gè)寫請求,會在每個(gè)ZooKeeper節(jié)點(diǎn)上保持寫一個(gè)事務(wù)日志,同時(shí)再加上定期的將內(nèi)存數(shù)據(jù)鏡像(Snapshot)到磁盤來保證數(shù)據(jù)的一致性和持久性,以及宕機(jī)之后的數(shù)據(jù)可恢復(fù),這是非常好的特性,但是我們要問,在服務(wù)發(fā)現(xiàn)場景中,其最核心的數(shù)據(jù)-實(shí)時(shí)的健康的服務(wù)的地址列表真的需要數(shù)據(jù)持久化么?
對于這份數(shù)據(jù),答案是否定的。
如上圖所示,如果 svcB 經(jīng)歷了注冊服務(wù)(ip1)到擴(kuò)容到2個(gè)節(jié)點(diǎn)(ip1,ip2)到因宕機(jī)縮容 (ip1 宕機(jī)),這個(gè)過程中,產(chǎn)生了3次針對 ZooKeeper 的寫操作。
但是仔細(xì)分析,通過事務(wù)日志,持久化連續(xù)記錄這個(gè)變化過程其實(shí)意義不大,因?yàn)樵诜?wù)發(fā)現(xiàn)中,服務(wù)調(diào)用發(fā)起方更關(guān)注的是其要調(diào)用的服務(wù)的實(shí)時(shí)的地址列表和實(shí)時(shí)健康狀態(tài),每次發(fā)起調(diào)用時(shí),并不關(guān)心要調(diào)用的服務(wù)的歷史服務(wù)地址列表、過去的健康狀態(tài)。
但是為什么又說需要呢,因?yàn)橐粋€(gè)完整的生產(chǎn)可用的注冊中心,除了服務(wù)的實(shí)時(shí)地址列表以及實(shí)時(shí)的健康狀態(tài)之外,還會存儲一些服務(wù)的元數(shù)據(jù)信息,例如服務(wù)的版本,分組,所在的數(shù)據(jù)中心,權(quán)重,鑒權(quán)策略信息,service label等元信息,這些數(shù)據(jù)需要持久化存儲,并且注冊中心應(yīng)該提供對這些元信息的檢索的能力。
Service Health Check
使用 ZooKeeper 作為服務(wù)注冊中心時(shí),服務(wù)的健康檢測常利用 ZooKeeper 的 Session 活性 Track機(jī)制 以及結(jié)合 Ephemeral ZNode的機(jī)制,簡單而言,就是將服務(wù)的健康監(jiān)測綁定在了 ZooKeeper 對于 Session 的健康監(jiān)測上,或者說綁定在TCP長鏈接活性探測上了。
這在很多時(shí)候也會造成致命的問題,ZK 與服務(wù)提供者機(jī)器之間的TCP長鏈接活性探測正常的時(shí)候,該服務(wù)就是健康的么?答案當(dāng)然是否定的!注冊中心應(yīng)該提供更豐富的健康監(jiān)測方案,服務(wù)的健康與否的邏輯應(yīng)該開放給服務(wù)提供方自己定義,而不是一刀切搞成了 TCP 活性檢測!
健康檢測的一大基本設(shè)計(jì)原則就是盡可能真實(shí)的反饋服務(wù)本身的真實(shí)健康狀態(tài),否則一個(gè)不敢被服務(wù)調(diào)用者相信的健康狀態(tài)判定結(jié)果還不如沒有健康檢測。
注冊中心的容災(zāi)考慮
前文提過,在實(shí)踐中,注冊中心不能因?yàn)樽陨淼娜魏卧蚱茐姆?wù)之間本身的可連通性,那么在可用性上,一個(gè)本質(zhì)的問題,如果注冊中心(Registry)本身完全宕機(jī)了,svcA 調(diào)用 svcB鏈路應(yīng)該受到影響么?
是的,不應(yīng)該受到影響。
服務(wù)調(diào)用(請求響應(yīng)流)鏈路應(yīng)該是弱依賴注冊中心,必須僅在服務(wù)發(fā)布,機(jī)器上下線,服務(wù)擴(kuò)縮容等必要時(shí)才依賴注冊中心。
這需要注冊中心仔細(xì)的設(shè)計(jì)自己提供的客戶端,客戶端中應(yīng)該有針對注冊中心服務(wù)完全不可用時(shí)做容災(zāi)的手段,例如設(shè)計(jì)客戶端緩存數(shù)據(jù)機(jī)制(我們稱之為 client snapshot)就是行之有效的手段。另外,注冊中心的 health check 機(jī)制也要仔細(xì)設(shè)計(jì)以便在這種情況不會出現(xiàn)諸如推空等情況的出現(xiàn)。
ZooKeeper的原生客戶端并沒有這種能力,所以利用 ZooKeeper 實(shí)現(xiàn)注冊中心的時(shí)候我們一定要問自己,如果把 ZooKeeper 所有節(jié)點(diǎn)全干掉,你生產(chǎn)上的所有服務(wù)調(diào)用鏈路能不受任何影響么?而且應(yīng)該定期就這一點(diǎn)做故障演練。
你有沒有ZooKeeper的專家可依靠?
ZooKeeper 看似很簡單的一個(gè)產(chǎn)品,但在生產(chǎn)上大規(guī)模使用并且用好,并不是那么理所當(dāng)然的事情。如果你決定在生產(chǎn)中引入 ZooKeeper,你最好做好隨時(shí)向 ZooKeeper 技術(shù)專家尋求幫助的心理預(yù)期,最典型的表現(xiàn)是在兩個(gè)方面:
- 難以掌握的Client/Session狀態(tài)機(jī)
ZooKeeper 的原生客戶端絕對稱不上好用,Curator 會好一點(diǎn),但其實(shí)也好的有限,要完全理解 ZooKeeper 客戶端與 Server 之間的交互協(xié)議也并不簡單,完全理解并掌握 ZooKeeper Client/Session 的狀態(tài)機(jī)(下圖)也并不是那么簡單明了:
但基于 ZooKeeper 的服務(wù)發(fā)現(xiàn)方案卻是依賴 ZooKeeper 提供的長連接/Session管理,Ephemeral ZNode,Event&Notification, ping 機(jī)制上,所以要用好ZooKeeper 做服務(wù)發(fā)現(xiàn),恰恰要理解這些 ZooKeeper 核心的機(jī)制原理,這有時(shí)候會讓你陷入暴躁,我只是想要個(gè)服務(wù)發(fā)現(xiàn)而已,怎么要知道這么多?而如果這些你都理解了并且不踩坑,恭喜你,你已經(jīng)成為ZooKeeper的技術(shù)專家了。
- 難以承受的異常處理
我們在阿里巴巴內(nèi)部應(yīng)用接入 ZooKeeper 時(shí),有一個(gè)《ZooKeeper 應(yīng)用接入必知必會》的 WIKI,其中關(guān)于異常處理有過如下的論述:
如果說要選出應(yīng)用開發(fā)者在使用ZooKeeper的過程中,最需要了解清楚的事情?那么根據(jù)我們之前的支持經(jīng)驗(yàn),一定是異常處理。
當(dāng)所有一切(宿主機(jī),磁盤,網(wǎng)絡(luò)等等)都很幸運(yùn)的正常工作的時(shí)候,應(yīng)用與ZooKeeper可能也會運(yùn)行的很好,但不幸的是,我們整天會面對各種意外,而且這遵循墨菲定律,意料之外的壞事情總是在你最擔(dān)心的時(shí)候發(fā)生。
所以務(wù)必仔細(xì)了解 ZooKeeper 在一些場景下會出現(xiàn)的異常和錯(cuò)誤,確保您正確的理解了這些異常和錯(cuò)誤,以及知道您的應(yīng)用如何正確的處理這些情況。
- ConnectionLossException 和 Disconnected 事件
簡單來說,這是個(gè)可以在同一個(gè) ZooKeeper Session 恢復(fù)的異常(Recoverable), 但是應(yīng)用開發(fā)者需要負(fù)責(zé)將應(yīng)用恢復(fù)到正確的狀態(tài)。
發(fā)生這個(gè)異常的原因有很多,例如應(yīng)用機(jī)器與ZooKeeper節(jié)點(diǎn)之間網(wǎng)絡(luò)閃斷,ZooKeeper節(jié)點(diǎn)宕機(jī),服務(wù)端Full GC時(shí)間超長,甚至你的應(yīng)用進(jìn)程Hang死,應(yīng)用進(jìn)程 Full GC 時(shí)間超長之后恢復(fù)都有可能。
要理解這個(gè)異常,需要了解分布式應(yīng)用中的一個(gè)典型的問題,如下圖:
在一個(gè)典型的客戶端請求、服務(wù)端響應(yīng)中,當(dāng)它們之間的長連接閃斷的時(shí)候,客戶端感知到這個(gè)閃斷事件的時(shí)候,會處在一個(gè)比較尷尬的境地,那就是無法確定該事件發(fā)生時(shí)附近的那個(gè)請求到底處在什么狀態(tài),Server端到底收到這個(gè)請求了么?已經(jīng)處理了么?因?yàn)闊o法確定這一點(diǎn),所以當(dāng)客戶端重新連接上Server之后,這個(gè)請求是否應(yīng)該重試(Retry)就也要打一個(gè)問號。
所以在處理連接斷開事件中,應(yīng)用開發(fā)者必須清楚處于閃斷附近的那個(gè)請求是什么(這常常難以判斷),該請求是否是冪等的,對于業(yè)務(wù)請求在Server端服務(wù)處理上對于"僅處理一次" "最多處理一次" "最少處理一次"語義要有選擇和預(yù)期。
舉個(gè)例子,如果應(yīng)用在收到 ConnectionLossException 時(shí),之前的請求是Create操作,那么應(yīng)用的catch到這個(gè)異常,應(yīng)用一個(gè)可能的恢復(fù)邏輯就是,判斷之前請求創(chuàng)建的節(jié)點(diǎn)的是否已經(jīng)存在了,如果存在就不要再創(chuàng)建了,否則就創(chuàng)建。
再比如,如果應(yīng)用使用了exists Watch 去監(jiān)聽一個(gè)不存在的節(jié)點(diǎn)的創(chuàng)建的事件,那么在ConnectionLossException的期間,有可能遇到的情況是,在這個(gè)閃斷期間,其它的客戶端進(jìn)程可能已經(jīng)創(chuàng)建了節(jié)點(diǎn),并且又已經(jīng)刪除了,那么對于當(dāng)前應(yīng)用來說,就miss了一次關(guān)心的節(jié)點(diǎn)的創(chuàng)建事件,這種miss對應(yīng)用的影響是什么?是可以忍受的還是不可接受?需要應(yīng)用開發(fā)者自己根據(jù)業(yè)務(wù)語義去評估和處理。
- SessionExpiredException 和 SessionExpired 事件
Session 超時(shí)是一個(gè)不可恢復(fù)的異常,這是指應(yīng)用Catch到這個(gè)異常的時(shí)候,應(yīng)用不可能在同一個(gè)Session中恢復(fù)應(yīng)用狀態(tài),必須要重新建立新Session,老Session關(guān)聯(lián)的臨時(shí)節(jié)點(diǎn)也可能已經(jīng)失效,擁有的鎖可能已經(jīng)失效。...
阿里巴巴的小伙伴在自行嘗試使用 ZooKeeper 做服務(wù)發(fā)現(xiàn)的過程中,曾經(jīng)在我們的內(nèi)網(wǎng)技術(shù)論壇上總結(jié)過一篇自己踩坑的經(jīng)驗(yàn)分享
在該文中中肯的提到:
... 在編碼過程中發(fā)現(xiàn)很多可能存在的陷阱,毛估估,第一次使用zk來實(shí)現(xiàn)集群管理的人應(yīng)該有80%以上會掉坑,有些坑比較隱蔽,在網(wǎng)絡(luò)問題或者異常的場景時(shí)才會出現(xiàn),可能很長一段時(shí)間才會暴露出來 ...
向左走,向右走
阿里巴巴是不是完全沒有使用 ZooKeeper?并不是。
熟悉阿里巴巴技術(shù)體系的都知道,其實(shí)阿里巴巴維護(hù)了目前國內(nèi)最大規(guī)模的ZooKeeper集群,整體規(guī)模有近千臺的ZooKeeper服務(wù)節(jié)點(diǎn)。
同時(shí)阿里巴巴中間件內(nèi)部也維護(hù)了一個(gè)面向大規(guī)模生產(chǎn)的、高可用、更易監(jiān)控和運(yùn)維的ZooKeeper的代碼分支TaoKeeper,如果以我們近10年在各個(gè)業(yè)務(wù)線和生產(chǎn)上使用ZooKeeper的實(shí)踐,給ZooKeeper 用一個(gè)短語評價(jià)的話,那么我們認(rèn)為ZooKeeper應(yīng)該是 “The King Of Coordination for Big Data”!
在粗粒度分布式鎖,分布式選主,主備高可用切換等不需要高TPS 支持的場景下有不可替代的作用,而這些需求往往多集中在大數(shù)據(jù)、離線任務(wù)等相關(guān)的業(yè)務(wù)領(lǐng)域,因?yàn)榇髷?shù)據(jù)領(lǐng)域,講究分割數(shù)據(jù)集,并且大部分時(shí)間分任務(wù)多進(jìn)程/線程并行處理這些數(shù)據(jù)集,但是總是有一些點(diǎn)上需要將這些任務(wù)和進(jìn)程統(tǒng)一協(xié)調(diào),這時(shí)候就是 ZooKeeper 發(fā)揮巨大作用的用武之地。
但是在交易場景交易鏈路上,在主業(yè)務(wù)數(shù)據(jù)存取,大規(guī)模服務(wù)發(fā)現(xiàn)、大規(guī)模健康監(jiān)測等方面有天然的短板,應(yīng)該竭力避免在這些場景下引入 ZooKeeper,在阿里巴巴的生產(chǎn)實(shí)踐中,應(yīng)用對ZooKeeper申請使用的時(shí)候要進(jìn)行嚴(yán)格的場景、容量、SLA需求的評估。
所以可以使用 ZooKeeper,但是大數(shù)據(jù)請向左,而交易則向右,分布式協(xié)調(diào)向左,服務(wù)發(fā)現(xiàn)向右。
結(jié)語
感謝你耐心的閱讀到這里,至此,我相信你已經(jīng)理解,我們寫這篇文章并不是全盤否定 ZooKeeper,而只是根據(jù)我們阿里巴巴在近10年來在大規(guī)模服務(wù)化上的生產(chǎn)實(shí)踐,對我們在服務(wù)發(fā)現(xiàn)和注冊中心設(shè)計(jì)及使用上的經(jīng)驗(yàn)教訓(xùn)進(jìn)行一個(gè)總結(jié),希望對業(yè)界就如何更好的使用 ZooKeeper,如何更好的設(shè)計(jì)自己的服務(wù)注冊中心有所啟發(fā)和幫助。
最后,條條大路通羅馬,衷心祝愿你的注冊中心直接就誕生在羅馬。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!