天天看點

Zookeeper概念學習系列之zookeeper是什麼?

1、 Zookeeper是Hadoop的分布式協調服務。

2、 分布式應用程式可以基于它,來實作同步服務,配置維護和命名服務等。

3、 zookeeper可以保證資料在zookeeper叢集之間的資料的事務性一緻。

前言

        Google的三篇論文影響了很多很多人,也影響了很多很多系統。這三篇論文一直是分布式領域傳閱的經典。根據MapReduce,于是我們有了Hadoop;根據GFS,于是我們有了HDFS;根據BigTable,于是我們有了HBase。而在這三篇論文裡都提及Google的一個lock service---Chubby,哦,于是我們有了Zookeeper。

        伴随着Zookeeper有兩篇論文:一篇是Zab,就是介紹Zookeeper背後使用的一緻性協定的(Zookeeper atomic broadcast protocol),還有一篇就是介紹Zookeeper本身的。在這兩篇論文裡都提到Zookeeper是一個分布式協調服務(a service for coordinating processes of distributed applications)。那分布式協調服務又是個什麼東西呢?首先我帶各位來看“協調”是什麼意思。

  zookeeper可謂是目前使用最廣泛的分布式元件了。其功能和職責單一,但卻非常重要。

在現今這個年代,介紹zookeeper的書和文章可謂多如牛毛,本人不才,試圖通過自己的了解來介紹zookeeper,希望通過一個初學者的視角來學習zookeeper,以期讓人更加深入和平穩的了解zookeeper。其中參考了不少教程和書,相關書目列在文末,也感謝這些作者。

學習新的架構,先讓我們搞清楚他是什麼,這是它的内涵,然後再介紹它能做什麼,這是它的外延,内涵和外延共同來定義架構本身,會對架構有較為深刻的了解,在應用層面上知道如何用。其次再搞清楚zookeeper相關的理論基礎,其目的是知道zookeeper是如何被發明的,是否能夠借鑒以便今後自己能夠用到其他地方。最後搞清楚zookeeper中一些設計的原理和細節,目的也是搞清來龍去脈,學會“術”進而應用到别的地方。當然了,加深的了解同樣能夠幫助認識zookeeper本身,在使用時才知道為什麼這樣用。

什麼是協調?

        說到協調,我首先想到的是北京很多十字路口的交通協管,他們手握着小紅旗,指揮車輛和行人是不是可以通行。如果我們把車輛和行人比喻成運作在計算機中的單元(線程),那麼這個協管是幹什麼的?很多人都會想到,這不就是鎖麼?對,在一個并發的環境裡,我們為了避免多個運作單元對共享資料同時進行修改,造成資料損壞的情況出現,我們就必須依賴像鎖這樣的協調機制,讓有的線程可以先操作這些資源,然後其他線程等待。對于程序内的鎖來講,我們使用的各種語言平台都已經給我們準備很多種選擇。

        就拿Java來說,有最普通不過的同步方法或同步塊:

        使用了這種方式後,多個線程對sharedMethod進行操作的時候,就會協調好步驟,不會對sharedMethod裡的資源進行破壞,産生不一緻的情況。這個最簡單的協調方法,但有的時候我們可能需要更複雜的協調。比如我們常常為了提高性能,我們使用讀寫鎖。因為大部分時候我們對資源是讀取多而修改少,而如果不管三七二十一全部使用排他的寫鎖,那麼性能有可能就會受到影響。

Zookeeper概念學習系列之zookeeper是什麼?
Zookeeper概念學習系列之zookeeper是什麼?

        我們在程序内還有各種各樣的協調機制(一般我們稱之為同步機制)。現在我們大概了解了什麼是協調了,但是上面介紹的協調都是在程序内進行協調。在程序内進行協調我們可以使用語言,平台,作業系統等為我們提供的機制。        

        那麼如果我們在一個分布式環境中呢?也就是我們的程式運作在不同的機器上,這些機器可能位于同一個機架,同一個機房又或不同的資料中心。在這樣的環境中,我們要實作協調該怎麼辦?那麼這就是分布式協調服務要幹的事情。

        ok,可能有人會講,這個好像也不難。無非是将原來在同一個程序内的一些原語通過網絡實作在分布式環境中。是的,表面上是可以這麼說。但分布式系統中,說往往比做容易得多。在分布式系統中,所有同一個程序内的任何假設都不存在:因為網絡是不可靠的。

        比如,在同一個程序内,你對一個方法的調用如果成功,那就是成功(當然,如果你的代碼有bug那就另說了),如果調用失敗,比如抛出異常那就是調用失敗。在同一個程序内,如果這個方法先調用先執行,那就是先執行。但是在分布式環境中呢? 由于網絡的不可靠,你對一個服務的調用失敗了并不表示一定是失敗的,可能是執行成功了,但是響應傳回的時候失敗了。還有,A和B都去調用C服務,在時間上A還先調用一些,B後調用,那麼最後的結果是不是一定A的請求就先于B到達呢? 這些本來在同一個程序内的種種假設我們都要重新思考,我們還要思考這些問題給我們的設計和編碼帶來了哪些影響。還有,在分布式環境中為了提升可靠性,我們往往會部署多套服務,但是如何在多套服務中達到一緻性,這在同一個程序内很容易解決的問題,但在分布式環境中确實一個大難題。

        是以分布式協調遠遠比同一個程序裡的協調複雜得多,是以類似Zookeeper這類基礎服務就應運而生。這些系統都在各個系統久經考驗,它的可靠性,可用性都是經過理論和實踐的驗證的。是以我們在建構一些分布式系統的時候,就可以以這類系統為起點來建構我們的系統,這将節省不少成本,而且bug也将更少。

Zookeeper是什麼?

  ZooKeeper---譯名為“動物園管理者”。動物園裡當然有好多的動物,遊客可以根據動物園提供的向導圖到不同的場館觀賞各種類型的動物,而不是像走在原始叢林裡,心驚膽顫的被動 物所觀賞。為了讓各種不同的動物呆在它們應該呆的地方,而不是互相串門,或是互相厮殺,就需要動物園管理者按照動物的各種習性加以分類和管理,這樣我們才能更加放心安全的觀賞動物。

    回到企業級應用系統中,随着資訊化水準的不斷提高,企業級系統變得越來越龐大臃腫,性能急劇下降,客戶抱怨頻頻。拆分系統是目前我們可選擇的解決系統可伸縮性和性能問題的唯一行之有效的方法。但是拆分系統同時也帶來了系統的複雜性——各子系統不是孤立存在的,它們彼此之間需要協作和互動,這就是我們常說的分布式系統0。各個子系統就好比動物園裡的動物,為了使各個子系統能正常為使用者提供統一的服務,必須需要一種機制來進行協調——這就是ZooKeeper(動物園管理者)。

Zookeeper概念學習系列之zookeeper是什麼?

ZooKeeper 是一個針對大型分布式系統的可靠協調系統。 

它提供的功能包括:配置維護、名字服務、分布式同步、組織服務等; 

它的目标就是封裝好複雜易出錯的關鍵服務,将簡單易用的接口和性能高效、功能穩定的系統提供給使用者; ZooKeeper 已經成為 Hadoop 生态系統中的基礎元件。

在Zookeeper的官網上有這麼一句話:ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. 

這大概描述了Zookeeper主要可以幹哪些事情:配置管理,名字服務,提供分布式同步、分布式鎖、監控以及叢集管理。

Zookeeper可以用來配置管理

        在我們的應用中除了代碼外,還有一些就是各種配置。比如資料庫連接配接等。一般我們都是使用配置檔案的方式,在代碼中引入這些配置檔案。但是當我們隻有一種配置,隻有一台伺服器,并且不經常修改的時候,使用配置檔案是一個很好的做法,但是如果我們配置非常多,有很多伺服器都需要這個配置,而且還可能是動态的話使用配置檔案就不是個好主意了。這個時候往往需要尋找一種集中管理配置的方法,我們在這個集中的地方修改了配置,所有對這個配置感興趣的都可以獲得變更。比如我們可以把配置放在資料庫裡,然後所有需要配置的服務都去這個資料庫讀取配置。但是,因為很多服務的正常運作都非常依賴這個配置,是以需要這個集中提供配置服務的服務具備很高的可靠性。一般我們可以用一個叢集來提供這個配置服務,但是用叢集提升可靠性,那如何保證配置在叢集中的一緻性呢? 這個時候就需要使用一種實作了一緻性協定的服務了。Zookeeper就是這種服務,它使用Zab這種一緻性協定來提供一緻性。現在有很多開源項目使用Zookeeper來維護配置,比如在HBase中,用戶端就是連接配接一個Zookeeper,獲得必要的HBase叢集的配置資訊,然後才可以進一步操作。還有在開源的消息隊列Kafka中,也使用Zookeeper來維護broker的資訊。在Alibaba開源的SOA架構Dubbo中也廣泛的使用Zookeeper管理一些配置來實作服務治理。

Zookeeper可以用來名字服務

        名字服務這個就很好了解了。比如為了通過網絡通路一個系統,我們得知道對方的IP位址,但是IP位址對人非常不友好,這個時候我們就需要使用域名來通路。但是計算機是不能是别域名的。怎麼辦呢?如果我們每台機器裡都備有一份域名到IP位址的映射,這個倒是能解決一部分問題,但是如果域名對應的IP發生變化了又該怎麼辦呢?于是我們有了DNS這個東西。我們隻需要通路一個大家熟知的(known)的點,它就會告訴你這個域名對應的IP是什麼。在我們的應用中也會存在很多這類問題,特别是在我們的服務特别多的時候,如果我們在本地儲存服務的位址的時候将非常不友善,但是如果我們隻需要通路一個大家都熟知的通路點,這裡提供統一的入口,那麼維護起來将友善得多了。

Zookeeper可以用來提供分布式同步

  ZkConfig是為zookeeper開發的配置服務工具包,能與現有的Java系統進行良好的內建,也可以使用與非java系統以獨立程序運作。提供與spring進行內建的插件。采用注解方式對需要動态更新的記憶體資料對象進行标注。

ZkConfig用于解決在系統叢集中配置檔案的實時同步。當任意一台伺服器配置檔案發生變化的時候,所有叢集伺服器配置檔案實作同步更新,并且在不啟動web容器的情況下,實作記憶體配置對象的實時更新。

目前支援所有種類配置檔案的同步更新,僅支援擴充名為.properties與.cfg結尾的健值對檔案格式的記憶體資料對象實時同步。其餘配置檔案僅支援磁盤資料同步。

Zookeeper可以用來分布式鎖(實用程式設計)

        Zookeeper是一個分布式協調服務。這樣我們就可以利用Zookeeper來協調多個分布式程序之間的活動。比如在一個分布式環境中,為了提高可靠性,我們的叢集的每台伺服器上都部署着同樣的服務。但是,一件事情如果叢集中的每個伺服器都進行的話,那互相之間就要協調,程式設計起來将非常複雜。而如果我們隻讓一個服務進行操作,那又存在單點。通常還有一種做法就是使用分布式鎖,在某個時刻隻讓一個服務去幹活,當這台服務出問題的時候鎖釋放,立即fail over到另外的服務。這在很多分布式系統中都是這麼做,這種設計有一個更好聽的名字叫Leader Election(leader選舉)。比如HBase的Master就是采用這種機制。但要注意的是分布式鎖跟同一個程序的鎖還是有差別的,是以使用的時候要比同一個程序裡的鎖更謹慎的使用。

Zookeeper可以用來監控(實用程式設計)

        這通常用于那種對叢集中機器狀态,機器線上率有較高要求的場景,能夠快速對叢集中機器變化作出響應。這樣的場景中,往往有一個監控系統,實時檢測叢集機器是否存活。

        利用ZooKeeper有兩個特性(讀可監控,臨時節點),就可以實作一種叢集機器存活性監控系統:

        1. 用戶端在節點 x 上注冊一個Watcher,那麼如果x的子節點變化了,會通知該用戶端2. 建立EPHEMERAL類型的節點,一旦用戶端和伺服器的會話結束或過期,那麼該節點就會消失利用這兩個特性,可以分别實作對客服端的狀态變化、上下線進行監控。

        例如,監控系統在 /Monitor 節點上注冊一個Watcher,以後每動态加機器,那麼就往 /Monitor 下建立一個 EPHEMERAL類型的節點:/Monitor/{hostname}. 這樣,監控系統就能夠實時知道機器的增減情況,至于後續處理就是監控系統的業務了。

Zookeeper可以用來叢集管理

        在分布式的叢集中,經常會由于各種原因,比如硬體故障,軟體故障,網絡問題,有些節點會進進出出。有新的節點加入進來,也有老的節點退出叢集。這個時候,叢集中其他機器需要感覺到這種變化,然後根據這種變化做出對應的決策。比如我們是一個分布式存儲系統,有一個中央控制節點負責存儲的配置設定,當有新的存儲進來的時候我們要根據現在叢集目前的狀态來配置設定存儲節點。這個時候我們就需要動态感覺到叢集目前的狀态。還有,比如一個分布式的SOA架構中,服務是一個叢集提供的,當消費者通路某個服務時,就需要采用某種機制發現現在有哪些節點可以提供該服務(這也稱之為服務發現,比如Alibaba開源的SOA架構Dubbo就采用了Zookeeper作為服務發現的底層機制)。還有開源的Kafka隊列就采用了Zookeeper作為Cosnumer的上下線管理。

 

zookeeper到底是什麼?

  zookeeper實際上是yahoo開發的,用于分布式中一緻性處理的架構。最初其作為研發hadoop時的副産品。由于分布式系統中一緻性處理較為困難,其他的分布式系統沒有必要 費勁重複造輪子,故随後的分布式系統中大量應用了zookeeper,以至于zookeeper成為了各種分布式系統的基礎元件,其地位之重要,可想而知。著名的hadoop,kafka,dubbo 都是基于zookeeper而建構。

 要想了解zookeeper到底是做啥的,那首先得了解清楚,什麼是一緻性。

所謂的一緻性,實際上就是圍繞着“看見”來的。誰能看見?能否看見?什麼時候看見?舉個例子:淘寶背景賣家,在背景上架一件大促的商品,通過伺服器A送出到主資料庫,假設剛送出後立馬就有使用者去通過應用伺服器B去從資料庫查詢該商品,就會出現一個現象,賣家已經更新成功了,然而買家卻看不到;而經過一段時間後,主資料庫的資料同步到了從資料庫,買家就能查到了。

假設賣家更新成功之後買家立馬就能看到賣家的更新,則稱為強一緻性;

如果賣家更新成功後買家不能看到賣家更新的内容,則稱為弱一緻性;

而賣家更新成功後,買家經過一段時間最終能看到賣家的更新,則稱為最終一緻性。

本文轉自大資料躺過的坑部落格園部落格,原文連結:http://www.cnblogs.com/zlslch/p/7242110.html,如需轉載請自行聯系原作者