[轉(zhuǎn)]云平臺發(fā)現(xiàn)服務(wù)構(gòu)建:為什么不使用ZooKeeper

本文作者通過ZooKeeper與Eureka作為 Service發(fā)現(xiàn)服務(wù)(注:WebServices 體系中的UDDI就是個發(fā)現(xiàn)服務(wù))的優(yōu)劣對比赘被,分享了Knewton在云計算平臺部署服務(wù)的經(jīng)驗是整。本文雖然略顯偏激,但是看得出Knewton在云平臺方面是非常有經(jīng)驗的民假,這篇文章從實踐角度出發(fā)分別從云平臺特點浮入、CAP原理以及運維三個方面對比了ZooKeeper與Eureka兩個系統(tǒng)作為發(fā)布服務(wù)的優(yōu)劣,并提出了在云平臺構(gòu)建發(fā)現(xiàn)服務(wù)的方法論羊异。

背景
  很多公司選擇使用 ZooKeeper作為Service發(fā)現(xiàn)服務(wù)(Service Discovery)事秀,但是在構(gòu)建 Knewton(Knewton 是一個提供個性化教育平臺的公司、學(xué)校和出版商可以通過Knewton平臺為學(xué)生提供自適應(yīng)的學(xué)習(xí)材料)平臺時野舶,我們發(fā)現(xiàn)這是個根本性的錯誤易迹。在這邊文章 中,我們將用我們在實踐中遇到的問題來說明平道,為什么使用ZooKeeper做Service發(fā)現(xiàn)服務(wù)是個錯誤睹欲。
  請留意服務(wù)部署環(huán)境
  讓我們從頭開始梳理。我們在部署服務(wù)的時候,應(yīng)該首先考慮服務(wù)部署的平臺(平臺環(huán)境)窘疮,然后才能考慮平臺上跑的軟件 系統(tǒng)或者如何在選定的平臺上自己構(gòu)建一套系統(tǒng)袋哼。例如,對于云部署平臺來說闸衫,平臺在硬件層面的伸縮(注:作者應(yīng)該指的是系統(tǒng)的冗余性設(shè)計涛贯,即系統(tǒng)遇到單點失 效問題,能夠快速切換到其他節(jié)點完成任務(wù))與如何應(yīng)對網(wǎng)絡(luò)故障是首先要考慮的蔚出。當(dāng)你的服務(wù)運行在大量服務(wù)器構(gòu)建的集群之上時(注:原話為大量可替換設(shè) 備)弟翘,則肯定會出現(xiàn)單點故障的問題。對于knewton來說,我們雖然是部署在AWS上的,但是在過往的運維中及舍,我們也遇到過形形色色的故障;所以,你應(yīng) 該把系統(tǒng)設(shè)計成“故障開放型”(expecting failure)的滚躯。其實有很多同樣使用AWS的 公司跟我們遇到了(同時有很多 書是介紹這方面的)相似的問題。你必須能夠提前預(yù)料到平臺可能會出現(xiàn)的問題如:意外故障(注:原文為box failure嘿歌,只能意會到作者指的是意外彈出的錯誤提示框)掸掏,高延遲與 網(wǎng)絡(luò)分割問題(注:原文為network partitions。意思是當(dāng)網(wǎng)絡(luò)交換機出故障會導(dǎo)致不同子網(wǎng)間通訊中斷)——同時我們要能構(gòu)建足夠彈性的系統(tǒng)來應(yīng)對它們的發(fā)生宙帝。
  永遠不要期望你部署服務(wù)的平臺跟其他人是一樣的!當(dāng)然丧凤,如果你在獨自運維一個數(shù)據(jù)中心,你可能會花很多時間與錢來避免硬件故障與網(wǎng)絡(luò)分割問題步脓,這 是另一種情況了;但是在云計算平臺中愿待,如AWS,會產(chǎn)生不同的問題以及不同的解決方式靴患。當(dāng)你實際使用時你就會明白仍侥,但是,你最好提前應(yīng)對它們(注:指的是 上一節(jié)說的意外故障鸳君、高延遲與網(wǎng)絡(luò)分割問題)的發(fā)生农渊。
  ZooKeeper作為發(fā)現(xiàn)服務(wù)的問題
  ZooKeeper(注:ZooKeeper是著名Hadoop的一個子項目,旨在解決大規(guī)模分 布式應(yīng)用場景下或颊,服務(wù)協(xié)調(diào)同步(Coordinate Service)的問題;它可以為同在一個分布式系統(tǒng)中的其他服務(wù)提供:統(tǒng)一命名服務(wù)砸紊、配置管理、分布式鎖服務(wù)囱挑、集群管理等功能)是個偉大的開源項目醉顽,它 很成熟,有相當(dāng)大的社區(qū)來支持它的發(fā)展平挑,而且在生產(chǎn)環(huán)境得到了廣泛的使用;但是用它來做Service發(fā)現(xiàn)服務(wù)解決方案則是個錯誤游添。
  在分布式系統(tǒng)領(lǐng)域有個著名的 CAP定理(C- 數(shù)據(jù)一致性;A-服務(wù)可用性;P-服務(wù)對網(wǎng)絡(luò)分區(qū)故障的容錯性,這三個特性在任何分布式系統(tǒng)中不能同時滿足石抡,最多同時滿足兩個);ZooKeeper是個 CP的,即任何時刻對ZooKeeper的訪問請求能得到一致的數(shù)據(jù)結(jié)果助泽,同時系統(tǒng)對網(wǎng)絡(luò)分割具備容錯性;但是它不能保證每次服務(wù)請求的可用性(注:也就 是在極端環(huán)境下隐解,ZooKeeper可能會丟棄一些請求,消費者程序需要重新請求才能獲得結(jié)果)诫睬。但是別忘了煞茫,ZooKeeper是分布式協(xié)調(diào)服務(wù),它的 職責(zé)是保證數(shù)據(jù)(注:配置數(shù)據(jù)摄凡,狀態(tài)數(shù)據(jù))在其管轄下的所有服務(wù)之間保持同步续徽、一致;所以就不難理解為什么ZooKeeper被設(shè)計成CP而不是AP特性 的了,如果是AP的亲澡,那么將會帶來恐怖的后果(注:ZooKeeper就像交叉路口的信號燈一樣钦扭,你能想象在交通要道突然信號燈失靈的情況嗎?)。而且床绪, 作為ZooKeeper的核心實現(xiàn)算法 Zab客情,就是解決了分布式系統(tǒng)下數(shù)據(jù)如何在多個服務(wù)之間保持同步問題的。
  作為一個分布式協(xié)同服務(wù)癞己,ZooKeeper非常好膀斋,但是對于Service發(fā)現(xiàn)服務(wù)來說就不合適了;因為對于Service發(fā)現(xiàn)服務(wù)來說就算是 返回了包含不實的信息的結(jié)果也比什么都不返回要好;再者,對于Service發(fā)現(xiàn)服務(wù)而言痹雅,寧可返回某服務(wù)5分鐘之前在哪幾個服務(wù)器上可用的信息仰担,也不能 因為暫時的網(wǎng)絡(luò)故障而找不到可用的服務(wù)器,而不返回任何結(jié)果练慕。所以說惰匙,用ZooKeeper來做Service發(fā)現(xiàn)服務(wù)是肯定錯誤的,如果你這么用就慘 了!
  而且更何況铃将,如果被用作Service發(fā)現(xiàn)服務(wù)项鬼,ZooKeeper本身并沒有正確的處理網(wǎng)絡(luò)分割的問題;而在云端,網(wǎng)絡(luò)分割問題跟其他類型的故障一樣的確會發(fā)生;所以最好提前對這個問題做好100%的準備劲阎。就像 Jepsen在 ZooKeeper網(wǎng)站上發(fā)布的博客中所說:在ZooKeeper中绘盟,如果在同一個網(wǎng)絡(luò)分區(qū)(partition)的節(jié)點數(shù)(nodes)數(shù)達不到 ZooKeeper選取Leader節(jié)點的“法定人數(shù)”時,它們就會從ZooKeeper中斷開,當(dāng)然同時也就不能提供Service發(fā)現(xiàn)服務(wù)了龄毡。
  如果給ZooKeeper加上客戶端緩存(注:給ZooKeeper節(jié)點配上本地緩存)或者其他類似技術(shù)的話可以緩解ZooKeeper因為網(wǎng)絡(luò)故障造成節(jié)點同步信息錯誤的問題吠卷。 Pinterest與 Airbnb公 司就使用了這個方法來防止ZooKeeper故障發(fā)生。這種方式可以從表面上解決這個問題沦零,具體地說祭隔,當(dāng)部分或者所有節(jié)點跟ZooKeeper斷開的情況 下,每個節(jié)點還可以從本地緩存中獲取到數(shù)據(jù);但是路操,即便如此疾渴,ZooKeeper下所有節(jié)點不可能保證任何時候都能緩存所有的服務(wù)注冊信息。如果 ZooKeeper下所有節(jié)點都斷開了屯仗,或者集群中出現(xiàn)了網(wǎng)絡(luò)分割的故障(注:由于交換機故障導(dǎo)致交換機底下的子網(wǎng)間不能互訪);那么ZooKeeper 會將它們都從自己管理范圍中剔除出去搞坝,外界就不能訪問到這些節(jié)點了,即便這些節(jié)點本身是“健康”的魁袜,可以正常提供服務(wù)的;所以導(dǎo)致到達這些節(jié)點的服務(wù)請求 被丟失了桩撮。(注:這也是為什么ZooKeeper不滿足CAP中A的原因)
  更深層次的原因是,ZooKeeper是按照CP原則構(gòu)建的峰弹,也就是說它能保證每個節(jié)點的數(shù)據(jù)保持一致店量,而為ZooKeeper加上緩存的做法的 目的是為了讓ZooKeeper變得更加可靠(available);但是,ZooKeeper設(shè)計的本意是保持節(jié)點的數(shù)據(jù)一致鞠呈,也就是CP垫桂。所以,這樣 一來粟按,你可能既得不到一個數(shù)據(jù)一致的(CP)也得不到一個高可用的(AP)的Service發(fā)現(xiàn)服務(wù)了;因為诬滩,這相當(dāng)于你在一個已有的CP系統(tǒng)上強制栓了 一個AP的系統(tǒng),這在本質(zhì)上就行不通的!一個Service發(fā)現(xiàn)服務(wù)應(yīng)該從一開始就被設(shè)計成高可用的才行!
  如果拋開CAP原理不管灭将,正確的設(shè)置與維護ZooKeeper服務(wù)就非常的困難;錯誤會 經(jīng)常發(fā)生疼鸟, 導(dǎo)致很多工程被建立只是為了減輕維護ZooKeeper的難度。這些錯誤不僅存在與客戶端而且還存在于ZooKeeper服務(wù)器本身庙曙。Knewton平臺 很多故障就是由于ZooKeeper使用不當(dāng)而導(dǎo)致的空镜。那些看似簡單的操作,如:正確的重建觀察者(reestablishing watcher)捌朴、客戶端Session與異常的處理與在ZK窗口中管理內(nèi)存都是非常容易導(dǎo)致ZooKeeper出錯的吴攒。同時,我們確實也遇到過 ZooKeeper的一些經(jīng)典bug: ZooKeeper-1159 與 ZooKeeper-1576; 我們甚至在生產(chǎn)環(huán)境中遇到過ZooKeeper選舉Leader節(jié)點失敗的情況砂蔽。這些問題之所以會出現(xiàn)洼怔,在于ZooKeeper需要管理與保障所管轄服務(wù) 群的Session與網(wǎng)絡(luò)連接資源(注:這些資源的管理在分布式系統(tǒng)環(huán)境下是極其困難的);但是它不負責(zé)管理服務(wù)的發(fā)現(xiàn),所以使用ZooKeeper當(dāng) Service發(fā)現(xiàn)服務(wù)得不償失左驾。
  做出正確的選擇:Eureka的成功
  我們把Service發(fā)現(xiàn)服務(wù)從ZooKeeper切換到了Eureka平臺镣隶,它是一個開 源的服務(wù)發(fā)現(xiàn)解決方案极谊,由Netflix公司開發(fā)。(注:Eureka由兩個組件組成:Eureka服務(wù)器和Eureka客戶端安岂。Eureka服務(wù)器用作 服務(wù)注冊服務(wù)器轻猖。Eureka客戶端是一個java客戶端,用來簡化與服務(wù)器的交互域那、作為輪詢負載均衡器咙边,并提供服務(wù)的故障切換支持。)Eureka一開 始就被設(shè)計成高可用與可伸縮的Service發(fā)現(xiàn)服務(wù)次员,這兩個特點也是Netflix公司開發(fā)所有平臺的兩個特色样眠。( 他們都在討論Eureka)。自從切換工作開始到現(xiàn)在翠肘,我們實現(xiàn)了在生產(chǎn)環(huán)境中所有依賴于Eureka的產(chǎn)品沒有下線維護的記錄。我們也被告知過辫秧,在云平臺做服務(wù)遷移注定要遇到失敗;但是我們從這個例子中得到的經(jīng)驗是束倍,一個優(yōu)秀的Service發(fā)現(xiàn)服務(wù)在其中發(fā)揮了至關(guān)重要的作用!
  首先,在Eureka平臺中盟戏,如果某臺服務(wù)器宕機绪妹,Eureka不會有類似于ZooKeeper的選舉leader的過程;客戶端請求會自動切換 到新的Eureka節(jié)點;當(dāng)宕機的服務(wù)器重新恢復(fù)后,Eureka會再次將其納入到服務(wù)器集群管理之中;而對于它來說柿究,所有要做的無非是同步一些新的服務(wù) 注冊信息而已邮旷。所以,再也不用擔(dān)心有“掉隊”的服務(wù)器恢復(fù)以后蝇摸,會從Eureka服務(wù)器集群中剔除出去的風(fēng)險了婶肩。Eureka甚至被設(shè)計用來應(yīng)付范圍更廣 的網(wǎng)絡(luò)分割故障,并實現(xiàn)“0”宕機維護需求貌夕。當(dāng)網(wǎng)絡(luò)分割故障發(fā)生時律歼,每個Eureka節(jié)點,會持續(xù)的對外提供服務(wù)(注:ZooKeeper不會):接收新 的服務(wù)注冊同時將它們提供給下游的服務(wù)發(fā)現(xiàn)請求啡专。這樣一來险毁,就可以實現(xiàn)在同一個子網(wǎng)中(same side of partition),新發(fā)布的服務(wù)仍然可以被發(fā)現(xiàn)與訪問们童。
  但是畔况,Eureka做到的不止這些。正常配置下慧库,Eureka內(nèi)置了心跳服務(wù)跷跪,用于淘汰一些“瀕死”的服務(wù)器;如果在Eureka中注冊的服務(wù), 它的“心跳”變得遲緩時齐板,Eureka會將其整個剔除出管理范圍(這點有點像ZooKeeper的做法)域庇。這是個很好的功能嵌戈,但是當(dāng)網(wǎng)絡(luò)分割故障發(fā)生時, 這也是非常危險的;因為听皿,那些因為網(wǎng)絡(luò)問題(注:心跳慢被剔除了)而被剔除出去的服務(wù)器本身是很”健康“的熟呛,只是因為網(wǎng)絡(luò)分割故障把Eureka集群分割 成了獨立的子網(wǎng)而不能互訪而已。
  幸運的是尉姨,Netflix考慮到了這個缺陷庵朝。如果Eureka服務(wù)節(jié)點在短時間里丟失了大量的心跳連接(注:可能發(fā)生了網(wǎng)絡(luò)故障),那么這個 Eureka節(jié)點會進入”自我保護模式“又厉,同時保留那些“心跳死亡“的服務(wù)注冊信息不過期九府。此時,這個Eureka節(jié)點對于新的服務(wù)還能提供注冊服務(wù)覆致,對 于”死亡“的仍然保留侄旬,以防還有客戶端向其發(fā)起請求。當(dāng)網(wǎng)絡(luò)故障恢復(fù)后煌妈,這個Eureka節(jié)點會退出”自我保護模式“儡羔。所以Eureka的哲學(xué)是,同時保 留”好數(shù)據(jù)“與”壞數(shù)據(jù)“總比丟掉任何”好數(shù)據(jù)“要更好璧诵,所以這種模式在實踐中非常有效汰蜘。
  最后,Eureka還有客戶端緩存功能(注:Eureka分為客戶端程序與服務(wù)器端程序兩個部分之宿,客戶端程序負責(zé)向外提供注冊與發(fā)現(xiàn)服務(wù)接口)族操。 所以即便Eureka集群中所有節(jié)點都失效,或者發(fā)生網(wǎng)絡(luò)分割故障導(dǎo)致客戶端不能訪問任何一臺Eureka服務(wù)器;Eureka服務(wù)的消費者仍然可以通過 Eureka客戶端緩存來獲取現(xiàn)有的服務(wù)注冊信息比被。甚至最極端的環(huán)境下色难,所有正常的Eureka節(jié)點都不對請求產(chǎn)生相應(yīng),也沒有更好的服務(wù)器解決方案來解 決這種問題時;得益于Eureka的客戶端緩存技術(shù)等缀,消費者服務(wù)仍然可以通過Eureka客戶端查詢與獲取注冊服務(wù)信息莱预,這點很重要。
  Eureka的構(gòu)架保證了它能夠成為Service發(fā)現(xiàn)服務(wù)项滑。它相對與ZooKeeper來說剔除了Leader節(jié)點的選取或者事務(wù)日志機制依沮,這 樣做有利于減少使用者維護的難度也保證了Eureka的在運行時的健壯性。而且Eureka就是為發(fā)現(xiàn)服務(wù)所設(shè)計的枪狂,它有獨立的客戶端程序庫危喉,同時提供心 跳服務(wù)、服務(wù)健康監(jiān)測州疾、自動發(fā)布服務(wù)與自動刷新緩存的功能辜限。但是,如果使用ZooKeeper你必須自己來實現(xiàn)這些功能严蓖。Eureka的所有庫都是開源 的薄嫡,所有人都能看到與使用這些源代碼氧急,這比那些只有一兩個人能看或者維護的客戶端庫要好。
  維護Eureka服務(wù)器也非常的簡單毫深,比如吩坝,切換一個節(jié)點只需要在現(xiàn)有EIP下移除一個現(xiàn)有的節(jié)點然后添加一個新的就行。Eureka提供了一個 web-based的圖形化的運維界面哑蔫,在這個界面中可以查看Eureka所管理的注冊服務(wù)的運行狀態(tài)信息:是否健康钉寝,運行日志等。Eureka甚至提供 了Restful-API接口闸迷,方便第三方程序集成Eureka的功能嵌纲。
  結(jié)論
  關(guān)于Service發(fā)現(xiàn)服務(wù)通過本文我們想說明兩點:1、留意服務(wù)運行的硬件平臺;2腥沽、時刻關(guān)注你要解決的問題逮走,然后決定 使用什么平臺。Knewton就是從這兩個方面考慮使用Eureka替換ZooKeeper來作為service發(fā)現(xiàn)服務(wù)的今阳。云部署平臺是充滿不可靠性 的师溅,Eureka可以應(yīng)對這些缺陷;同時Service發(fā)現(xiàn)服務(wù)必須同時具備高可靠性與高彈性,Eureke就是我們想要的!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酣栈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子汹押,更是在濱河造成了極大的恐慌矿筝,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棚贾,死亡現(xiàn)場離奇詭異窖维,居然都是意外死亡,警方通過查閱死者的電腦和手機妙痹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門铸史,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人怯伊,你說我怎么就攤上這事琳轿。” “怎么了耿芹?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵崭篡,是天一觀的道長。 經(jīng)常有香客問我吧秕,道長琉闪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任砸彬,我火速辦了婚禮颠毙,結(jié)果婚禮上斯入,老公的妹妹穿的比我還像新娘。我一直安慰自己蛀蜜,他們只是感情好刻两,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著涵防,像睡著了一般闹伪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上壮池,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天偏瓤,我揣著相機與錄音,去河邊找鬼椰憋。 笑死厅克,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的橙依。 我是一名探鬼主播证舟,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼窗骑!你這毒婦竟也來了女责?” 一聲冷哼從身側(cè)響起创译,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤软族,失蹤者是張志新(化名)和其女友劉穎掖疮,沒想到半個月后螺戳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體规揪,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年温峭,在試婚紗的時候發(fā)現(xiàn)自己被綠了猛铅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡凤藏,死狀恐怖奸忽,靈堂內(nèi)的尸體忽然破棺而出堕伪,到底是詐尸還是另有隱情,我是刑警寧澤栗菜,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布欠雌,位于F島的核電站,受9級特大地震影響疙筹,放射性物質(zhì)發(fā)生泄漏富俄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一而咆、第九天 我趴在偏房一處隱蔽的房頂上張望霍比。 院中可真熱鬧,春花似錦暴备、人聲如沸悠瞬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浅妆。三九已至,卻和暖如春障癌,著一層夾襖步出監(jiān)牢的瞬間凌外,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工涛浙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留康辑,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓蝗拿,卻偏偏與公主長得像晾捏,于是被迫代替她去往敵國和親蒿涎。 傳聞我的和親對象是個殘疾皇子哀托,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容