快速瞭解zookeeper

前言

zookeeper本質上就是一個分佈式協調服務,用來解決分佈式一致性的問題。java


本文適合有必定分佈式基礎的讀者閱讀。什麼叫相關的基礎呢?起碼你得知道系統架構爲什麼從集中式演變成了分佈式,分佈式有哪些優勢和問題。基於分佈式的問題,適當的學習下CAP,知道分佈式面臨了什麼的問題以及如何根據業務特色在C(一致性)和A(可用性)之間尋求平衡。以後學習下e-bay的架構師提出的BASE理論,BASE是CAP中一致性和可用性權衡的結果,來源於大規模互聯網分佈式系統的總結,其核心思想是使服務在一個基本可用的狀態下,根據業務的特色使用適當的方式使系統達到最終一致性。在對一個分佈式系統進行架構設計中,每每會在系統的可用性和一致性作權衡,瞭解一下經典的分佈式一致性協議也是極好的。好比著名的2pc、3pc、以及paxos協議,明白各自的優缺點。mysql


若是你對上述部份內容感到很是陌生,尤爲是關於CPA和BASE的理論知識都不太清楚的話,最好先補一下相關的基礎,由於這是指導全部分佈式架構理論的基石。這裏推薦一本書能夠系統的學習分佈式理論和zookeeper,本人對於zookeeper的學習大部分也是基於此書《從Paxos到Zookeeper分佈式一致性原理與實踐》.redis


友情提示:本文是對《從Paxos到Zookeeper分佈式一致性原理與實踐》的一個簡單總結,方便做者本人也就是我本身日常翻閱看,快速過一下zookeeper的各個點。若是你讀起來有點吃力,徹底不知所云且對zookeeper又有一絲絲興趣,那麼老老實實看書吧~。算法

初識zookeeper

  • zookeeper介紹

    zookeeper是由hadoop的子項目發展而來,爲分佈式應用提供了高效且可靠的分佈式協調服務,提供了命名服務、配置管理、分佈式鎖和Master選舉等分佈式的基礎服務。在解決分佈式一致性方面,zookeeper沒有直接採用paxos算法,而是採用了ZAB(Zookeeper Atomic Broadcast)的一致性協議。sql

  • zookeeper的5個特性
    1.順序一致性:從同一個客戶端發送的事務請求,最終將嚴格的按照其發起順序被應用到Zookeeper中去。
    2.原子性:全部事務請求的結果在集羣中全部機器上的應用狀況是一致的,也就是說要麼集羣內全部的機器都應用了某一事務,要麼都沒有應用。
    3.單一視圖:不管哪一個客戶端鏈接的zookeeper服務器,其看到的數據模型都是一致的。
    4.可靠性:一旦服務器成功應用了某一個事務,那麼該事務引發的服務端狀態變動將會被一直保留下來,除非另外一個事務又對其進行了變動。
    5.實時性:一旦一個事務被成功應用後,zookeeper不能當即保證能夠從讀取到事務變動後的最新數據狀態,它只能保證在必定的時間段內,客戶端最終能從服務端上讀取到新的數據狀態。
  • zookeeper的四個設計目標
    1.簡單的數據模型:zookeeper使得分佈式系統共享一個樹形結構的名字空間來進行相互協調。樹形結構中最小的數據節點就是ZNODE。總的來講,其數據模型相似於一個文件系統,而ZNODE之間的層級關係,就像文件系統的目錄結構同樣。不過zookeeper選擇將全量數據存儲在內存中,以此來實現提升服務器吞吐、減小延遲的目的。
    2.能夠構建集羣:一個zookeeper集羣一般由一組機器組成,通常3~5臺機器就能夠組成一個可用的集羣。zookeeper集羣之間的每臺機器都會在內存中維護當前的服務器狀態,而且每臺機器之間互相保持通訊。只要集羣中超過一半機器存活,集羣就能夠正常對外提供服務。zookeeper的客戶端會選擇集羣中任意一臺機器共同來建立一個TCP鏈接,一旦鏈接斷開後,客戶端會自動鏈接到集羣中的其餘機器。
    3.順序訪問:對於每個更改數據狀態的事務請求,zookeeper都會分配一個全局惟一的遞增編號,這個編號反映了全部事務操做的前後順序。
    4.高性能:zookeeper將全量數據存儲到內存中,並直接服務於客戶端的全部非事務請求,所以它尤爲適用以讀操做爲主的應用場景。
  • zookeeper的基本概念
    1.集羣角色:最典型的的集羣模式就是Master/Slave模式。在這種模式中將處理全部寫操做的機器稱爲Master機器,把經過異步複製方式獲取最新數據並提供讀服務的機器稱爲Slave機器。而zookeeper沒有選擇這種經典模式,而是引入了Leader、Follower和Observer三種角色。zookeeper經過leader選舉過程選舉集羣中的一臺機器爲leader服務器,leader服務器爲客戶端同時提供讀服務和寫服務,且只有leader能夠提供寫服務。Follower和Observer都提供讀服務,惟一的區別在於observer機器不參與leader選舉過程,也不參與寫操做的過半寫成功的策略。所以若在不影響寫性能的狀況下提高集羣的讀性能增長observer就對了!
    2.會話:在講解會話以前,先來了解下客戶端鏈接。在zookeeper中,一個客戶端鏈接指的是客戶端月服務器之間的一個TCP長鏈接。zookeeper對外的服務端口默認是2181,客戶端啓動的時候首先會與服務端創建一個TCP鏈接,從第一次鏈接創建開始,客戶端的會話週期就開始了,客戶端經過心跳檢測與服務端保持有效的會話,也能夠經過該鏈接接收來自服務器的watch事件通知
    3:數據節點:zookeeper將全部數據存儲在內存中,數據模型是一顆樹(ZNode Tree),由斜槓(/)進行分割的路徑就是一個ZNode,例如/dubbo/provider/com.bin.IUserService,每一個ZNode都會保存本身的數據內容,同時還會保存一系列屬性信息。在zookeeper中ZNode分爲持久節點和臨時節點兩類。所謂持久節點就是一旦ZNode節點被建立成功了,除非主動進行該ZNode的移除操做,不然這個ZNode將會一直保存在zookeeper集羣中。而臨時節點就不同了,它的生命週期和客戶端會話綁定,一旦客戶端會話失效,那這個客戶端建立的全部臨時節點都會被移除。另外zookeeper還容許每個節點增長一個特殊的屬性:SEQUENTIAL,也就是有序性。一旦節點被標記上這個屬性,那麼這個節點被建立的時候,zookeeper都會在節點名字後面追加上一個整形數字,這個數字是一個由父節點維護的自增數字。全部節點必爲持久節點,換言之只有是持久節點纔能有子節點。
    4:Watcher:事件監聽器,是zookeeper中一個很是重要的特性。zookeeper容許用戶在指定節點上註冊一些Watcher,並在一些特定事件觸發的時候,zookeeper會經過於客戶端會話的鏈接將事件通知到註冊的客戶端上去,該機制是zookeeper實現分佈式協調服務的重要特性。但須要知道Watcher是一個消耗品,每次使用都須從新註冊,若是你使用的是zookeeper原生客戶端須要注意這點,好在zkclient和curator客戶端會每次幫你從新註冊watcher,幫咱們省掉了一些沒必要要的代碼。
  • zookeeper的ZAB協議
    zookeeper沒有徹底採用Paxos算法,而是使用了一種Zookeeper Atomic Broadcast(ZAB,Zookeeper原子消息廣播協議)的協議做爲數據一致性的核心算法。ZAB協議的核心是定義了對於那些會改變Zookeeper服務器數據狀態的事務請求的處理方式,即:全部的事務請求必須由一個全局惟一的服務器來處理,這樣的服務器被稱爲leader服務器,而餘下的服務器則被稱爲follower服務器。leader服務器負責將一個客戶端事務請求轉換成一個事務Proposal(提議),並將該Proposal分發給集羣中全部的Follwer服務器。以後leader服務器等待其餘follower服務器的反饋,一旦超過半數的follwer服務器進行了正確的反饋,那麼leader就會再次向全部的follwer服務器分發commit消息,要求其將前一個proposal進行提交。
    ZAB協議包括兩種基本的模式,分別是崩潰恢復和消息廣播。當整個服務框架在啓動時,或是當leader服務器出現網絡中斷、崩潰退出與重啓等異常狀況時,ZAB協議就會進入恢復模式並選舉新的leader。當選舉完leader以後,同時集羣中有過半的機器與該leader服務器完成了狀態同步以後,ZAB就會退出恢復模式,進入消息廣播模式。當有一個新的聽從ZAB協議的服務器加入到集羣當中,若是此時已經存在一個leader服務器在負責進行消息廣播,那麼新加入的服務器就會自覺地找到leader服務器進行數據同步,而後一塊兒參與到消息廣播流程中去。
    上面從概念上簡單介紹了ZAB協議,有對ZAB協議實現細節感興趣的能夠去翻看文首推薦的書,亦或是Andr´e Medeiros的論文

zookeeper的應用場景

  • 數據發佈/訂閱
    數據發佈/訂閱系統,即所謂的配置中心,其實就是發佈者將數據發佈到Zookeeper上,供訂閱者進行數據訂閱,利用watcher機制進行動態獲取數據的目的,實現分佈式架構中配置信息的集中管理和數據的動態更新。百度開源的disconf就是典型這種場景的實現。
  • 註冊中心
    阿里巴巴開源的框架dubbo相信大部分人都多多少少的有些瞭解,它是一個致力於提供高性能和透明化的遠程服務調用方案和基於服務框架展開的完整SOA服務治理方案。在這,咱們主要聊下dubbo中基於zookeeper實現的服務註冊中心。註冊中心是RPC框架中最核心的模塊之一,用於服務的註冊和訂閱。假設如今有一個應用,提供了一個rpc服務com.bin.IBinService。服務提供者在初始化啓動時,會在zookeeper集羣中對應的目錄下/dubbo/com.bin.IBinSerivce/providers節點下建立一個子節點,並寫入本身的URL地址,這就表明了IBinService這個服務的一個提供者,如有多個服務提供者,同理zookeeper也會生成多個子節點。服務消費者會在zookeeper的/dubbo/com.bin.IBinSerivce/consumers節點下建立一個臨時節點,並寫入本身的url地址,這就表明了這個服務的一個消費者。dubbo做爲一個完成的soa服務治理框架,也提供了集羣容錯和軟負載的功能,都是從zookeeper上拉取全部的提供者,根據設置的策略進行。
  • Master選舉
    master選舉是一個在分佈式系統中很是常見的應用場景。接下來,咱們重點看master選舉的過程。在集羣的全部機器中選出一臺機器做爲master,針對這個需求,咱們能夠選擇常見的關係型數據庫的主鍵特性來實現:集羣中全部機器向數據庫中插入一條相同主鍵ID的記錄,數據庫會幫助咱們保證主鍵的惟一性和衝突檢查,也就是說成功的那臺機器將成爲master。但這個方案的致命缺點就是若是當前的master掛了,怎麼處理?顯然數據庫無法通知咱們這個事件,咱們能夠經過zookeeper垂手可得的作到這一點。利用zookeeper的強一致性,可以很好地保證在分佈式高併發環境下節點的建立必定可以保證全局惟一性。若是有多個客戶端同時建立同一個節點,那麼最終必定只有一個客戶端可以請求建立成功。利用這個特性,就能夠很容易的在分佈式環境進行Master選舉了。假如master掛了,如何根據zookeeper進行動態master選舉呢?集羣中全部機器都會向zookeeper定時建立一個臨時節點(/master_election/2018/leader),只有一臺機器可以成功建立這個節點,那麼這臺機器就成爲了master。同時其餘沒有建立成功的機器都會在節點(/master_election/2018)上註冊一個子節點變動的watcher,用於監控當前的master機器是否存活,一旦發現當前的master掛了,那麼其他的機器將會進行Master選舉.
  • 分佈式鎖
    常見的分佈式鎖有三種實現方式,基於mysql,redis和zookeeper的。分佈式鎖是控制分佈式系統之間同步訪問共享資源的一種方式。在一般的java開發編程中,有兩種常見的鎖,分別是synchronized機制和JDK5提供的ReentranLock。zookeeper是使用了一個數據節點來表示爲一個鎖。在須要去獲取鎖時,全部的客戶端都會去建立一個節點,好比:/exclusive_lock/lock,zookeeper會保證只有一個客戶端可以建立成功,,那麼就認爲該客戶端獲取了鎖。同時其餘全部沒有得到到鎖的客戶端就須要到/exclusive_lock節點下注冊一個子節點變動的watcher監聽,以便實時監聽到lock節點消失,通知其餘客戶端去從新建立節點得到分佈式鎖。

常見的應用場景已經講完了,或許你有些迷迷糊糊,以爲太理論了,我想要看代碼。其實基礎理論知識若是懂了,代碼是很簡單的。這裏給你們推薦一個好用的客戶端,Netflix公司開源的一套zookeeper客戶端框架:Curator。它是目前全世界範圍內使用最普遍的zookeeper客戶端。它處理了許多很是底層的細節工做,包括鏈接重連、反覆註冊watcher和各類ZNODE異常,而且它還提供了zookeeper各類應用場景(Recipe,master選舉和共享鎖)的抽象封裝。若是你想看zookeeper自己是怎麼實現的,那你就看zookeeper原生客戶端。若是你想要使用zookeeperAPI,那必定首選Curator。數據庫

zookeeper的一些細節

  • 數據模型
    zookeeper的視圖結構與unix文件系統很是相似,但他沒有引入傳統文件系統中目錄和文件的概念,而是使用了特有的數據節點ZNode。ZNode是zookeeper中數據最小單元,每一個ZNode上均可以保存數據,同時還能夠掛載子節點,所以造成了一棵樹。

圖片描述

  • 節點特性
    在zookeeper中,每一個數據節點都是有生命週期的。整體可分爲三類:持久節點(PERSISTENT),臨時節點(EPHEMERAL)和順序節點(SEQUENTIAL),具體在使用過程當中。能夠生成四種組合類型:持久節點、持久順序節點、臨時節點、臨時順序節點。
    持久節點:zookeeper最多見的節點類型。一旦被建立後,就會一直存在zookeeper服務器上,直到有操做來主動清除這個節點。
    持久順序節點:相對於持久節點,它額外的特性表如今順序性上。在zookeeper中,每一個父節點都會爲它的第一級子節點維護一份順序,用於記錄下節點被建立的前後順序。基於這個特性,在建立子節點的時候,能夠設置這個標記,生成的節點名稱就會添加一個數字後綴做爲新的節點名。值得注意的是數字後綴的上限是整型的最大值。
    臨時節點:它的生命週期和客戶端的會話綁定在一塊兒,也就是說,若是客戶端會話失效,這個節點會被自動清除。zookeeper規定了不能基於臨時節點來建立子節點,也就是子節點只能成爲葉子節點。
    臨時順序節點:和臨時節點同樣,也是多出了順序的特性。
  • Watcher
    一個典型的發佈訂閱系統定義了一種一對多的訂閱關係,可以讓多個訂閱者同時監聽某一個主題對象,當這個主題對象自身狀態變化時,會通知全部訂閱者,使他們能作出相應的處理。zookeeper中使用了watcher機制來實現這種分佈式的通知功能。zookeeper容許客戶端向服務端註冊一個watcher監聽,當服務端的 一些指定事件觸發了這個Watcher,那麼就會像指定的客戶端發送一個事件通知來實現分佈式的通知功能。整個流程以下圖所示:
    圖片描述
  • 服務期間的角色介紹 在zookeeper集羣中,分別有leader、follwer和observer三種類型的服務器角色。 leader:它是整個zookeeper集羣中工做的核心,它是事務請求的惟一調度和處理者,保證集羣事務處理的順序性,同事它也是集羣內部各服務器的調度者。 follwer:follwer服務器是zookeeper集羣狀態的跟隨者,其主要工做有:處理客戶端非事務請求,轉發事務請求給leader服務器,參與事務請求的proposal的投票,參與leader選舉投票 observer:observer服務器充當了一個觀察者的角色,它會觀察zookeeper最新的集羣狀態並同步過來。它的工做原理和follwer基本上是同樣的,對於非事務請求均可以進行獨立的處理,對於非事務請求,會轉發給leader服務器進行處理。和follwer惟一的區別就是,不參與事務請求proposal和leadr選舉的投票。簡單的說,observer只提供非事務服務,用於不影響集羣事務處理能力的前提下提高集羣地非事務處理能力。
相關文章
相關標籤/搜索