Zookeeper機制

顧名思義 zookeeper 就是動物園管理員,他是用來管 hadoop(大象)、Hive(蜜蜂)、pig(小 豬)的管理員, Apache Hbase 和 Apache Solr 的分佈式集羣都用到了 zookeeper;Zookeeper: 是一個分佈式的、開源的程序協調服務,是 hadoop 項目下的一個子項目。他提供的主要功 能包括:配置管理、名稱服務、分佈式鎖、集羣管理。node

功能特性

  1. 最終一致性:client 不論鏈接到哪一個 Server,展現給它都是同一個視圖,這是 zookeeper 最重要的性能。
  2. 可靠性:具備簡單、健壯、良好的性能,若是消息 m 被到一臺服務器接受,那麼它 將被全部的服務器接受。
  3. 實時性:Zookeeper 保證客戶端將在一個時間間隔範圍內得到服務器的更新信息,或 者服務器失效的信息。但因爲網絡延時等緣由,Zookeeper 不能保證兩個客戶端能同時獲得 剛更新的數據,若是須要最新數據,應該在讀數據以前調用 sync()接口。
  4. 等待無關(wait-free):慢的或者失效的 client 不得干預快速的 client 的請求,使得每 個 client 都能有效的等待。
  5. 原子性:更新只能成功或者失敗,沒有中間狀態。
  6. 順序性:包括全局有序和偏序兩種:全局有序是指若是在一臺服務器上消息 a 在消息 b 前發佈,則在全部 Server 上消息 a 都將在消息 b 前被髮布;偏序是指若是一個消息 b 在消 息 a 後被同一個發送者發佈,a 必將排在 b 前面。算法

    進程角色

  • leader:由集羣成員投票選舉出來的領導者,負責處理外部發到集羣的讀寫請求,處理寫請求時會發起投票,只有集羣內超過半數節點經過後寫操做纔會被經過。
  • follower:負責處理都請求並返回結果,若是接收到寫請求則將之轉發給leader,還要負責leader選舉時的投票。
  • observer:能夠理解爲沒有選舉權的follower,只負責處理業務,時爲了提升集羣吞吐率,同時又能保證集羣快速完成選舉而引進的機制。數據庫

    機制

  1. 集羣的兩種模式
  • 恢復模式:集羣的一種非穩定狀態,集羣不能處理外部請求;集羣啓動或遇到leader崩潰時,集羣進入恢復模式,在本模式中選舉leader,leader選舉完成後其餘節點與leader進行數據同步,當過半節點完成同步後恢復模式結束,進入廣播模式。
  • 廣播模式:集羣的穩定狀態,集羣能正常的處理外部請求;此時如有新節點加入,新節點會自動從leader同步數據。
  1. 集羣啓動過程:
    • leader選舉原則
      • 集羣中只有超過半數的節點處於正常狀態,集羣才能穩定,才能處理外部請求。
      • 集羣正常工做以前myid小的節點會優先給myid大的節點投票,直到選出leader爲止。
      • 選出leader以前,集羣全部節點都處於looking狀態,選舉成功後,除leader節點外,其他節點的狀態由looking變爲following,角色也成爲了follower。
    • leader選舉過程
      • 假設集羣有5個節點,myid分別爲1~5,假設集羣第一次啓動,全部節點都沒有歷史數據,啓動順序1~5。由集羣節點數量可知,至少要有3個節點正常,集羣才能穩定工做。
      • 節點1啓動,其初始狀態爲looking,發起一輪選舉,節點1投本身一票,因爲不過半,本輪選舉沒法完成。節點1仍然保持looking狀態。
      • 節點2啓動,其初始狀態爲looking,它也發起一輪選舉,節點2投本身一票;節點1也參與進本輪投票,打算給本身投一票,可是發現節點2的myid比本身的大,就改投節點2一票;本輪投票事後節點1得0票,節點2得2票,因爲節點2的得票數不過半,因此本輪選舉未能完成;節點一、2都保持looking狀態。
      • 節點3啓動,其初始狀態爲looking,它也發起一輪選舉,且節點3先投本身一票;節點一、2也都參與進本輪投票中來,打算投本身一票,發現本輪中節點3的myid大於本身的,因此節點一、2都轉投節點3一票;此時節點3就收穫了3票,超過了集羣節點的半數,節點3率先當選,並從looking狀態變爲leading狀態。節點一、2的狀態變爲following。
      • 節點4啓動,其初始狀態爲looking,它也發起一輪選舉;此時因爲節點一、2處於following狀態,這兩個節點就不參與本輪選舉。節點4本打算投本身一票,可是發現節點3已進入leading狀態,且票數已通過半,此時節點4就會將本身的一票轉投給節點3。節點4未收到投票,狀態由looking變爲following。
      • 節點5的啓動過程與節點4同樣,最終未得到投票,也處於following狀態。
      • 最終節點3成爲leader,節點一、二、四、5成爲follower。
  2. 崩潰恢復過程:當leader崩潰後,集羣中的其餘follower節點會從新變爲looking狀態,從新進行leader選舉。選舉過程同啓動時的leader選舉同樣。
  3. 消息廣播算法:
    • leader接收到一個寫請求後,leader會給此請求標記一個全局自增的64位事務id(zxid)。
    • leader以隊列未載體將每一個事務依此發送給follower,follower讀取也嚴格遵循隊列的順序,這就避免了paxos算法的全序問題。
    • follower在本地緩存了它最新執行的事務的zxid,當接收到新事務後,會取出zxid與本地的zxid作比較,若是接收到的zxid大於本地的就執行此事務並給leader返回確認消息,不然拒絕執行。
    • 當leader接收到過半數量的follower確認消息後,表明着事務已在整個集羣中執行,leader就給全部follower發送事務提交指令。
      zxid:是一個32+32位的數字;前32位稱爲epochId,是當前leader的全局自增編號,若是把leader比做皇帝,那epochId則是皇帝的年號。後32位是每一個事務特定的標識,至關於皇帝發佈的號令,對一個皇帝來講這個編號也是全局自增的。apache

      數據結構

  4. Znode
    在 Zookeeper 中,znode 是一個跟 Unix 文件系統路徑類似的節點,能夠往這個節點存儲 或獲取數據。 Zookeeper 底層是一套數據結構。這個存儲結構是一個樹形結構,其上的每個節點, 咱們稱之爲「znode」 zookeeper 中的數據是按照「樹」結構進行存儲的。並且 znode 節點還分爲 4 中不一樣的類 型。 每個 znode 默認可以存儲 1MB 的數據(對於記錄狀態性質的數據來講,夠了) 可使用 zkCli 命令,登陸到 zookeeper 上,並經過 ls、create、delete、get、set 等命令 操做這些 znode 節點
  5. Znode 節點類型
  • PERSISTENT 持久化節點: 所謂持久節點,是指在節點建立後,就一直存在,直到 有刪除操做來主動清除這個節點。不然不會由於建立該節點的客戶端會話失效而消失。
  • PERSISTENT_SEQUENTIAL 持久順序節點:這類節點的基本特性和上面的節點類 型是一致的。額外的特性是,在 ZK 中,每一個父節點會爲他的第一級子節點維護一份時序, 會記錄每一個子節點建立的前後順序。基於這個特性,在建立子節點的時候,能夠設置這個屬 性,那麼在建立節點過程當中,ZK 會自動爲給定節點名加上一個數字後綴,做爲新的節點名。 這個數字後綴的範圍是整型的最大值。 在建立節點的時候只須要傳入節點 「/test_」,這樣 以後,zookeeper 自動會給」test_」後面補充數字。
  • EPHEMERAL 臨時節點:和持久節點不一樣的是,臨時節點的生命週期和客戶端會 話綁定。也就是說,若是客戶端會話失效,那麼這個節點就會自動被清除掉。注意,這裏提 到的是會話失效,而非鏈接斷開。另外,在臨時節點下面不能建立子節點。 這裏還要注意一件事,就是當你客戶端會話失效後,所產生的節點也不是一會兒就消失 了,也要過一段時間,大概是 10 秒之內,能夠試一下,本機操做生成節點,在服務器端用 命令來查看當前的節點數目,你會發現客戶端已經 stop,可是產生的節點還在。
  • EPHEMERAL_SEQUENTIAL 臨時自動編號節點:此節點是屬於臨時節點,不過帶 有順序,客戶端會話結束節點就消失。編程

    目錄結構

  1. bin:放置運行腳本和工具腳本,若是是 Linux 環境還會有有 zookeeper 的運 行日誌 zookeeper.out
  2. conf:zookeeper 默認讀取配置的目錄,裏面會有默認的配置文件
  3. contrib:zookeeper 的拓展功能
  4. dist-maven:zookeeper的 maven 打包目錄
  5. docs:zookeeper 相關的文檔
  6. lib:zookeeper 核心的 jar
  7. recipes:zookeeper 分佈式相關的 jar 包
  8. src:zookeeper 源碼緩存

    單機部署

    Zookeeper 在啓動時默認的去 conf 目錄下查找一個名稱爲 zoo.cfg 的配置文件。 在 zookeeper 應用目錄中有子目錄 conf。其中有配置文件模板,手動拷貝重命名:zoo_sample.cfg cp zoo_sample.cfg zoo.cfg。zookeeper 應用中的配置文件爲 conf/zoo.cfg。 修改配置文件 zoo.cfg - 設置數據緩存路徑
  • 安裝jdk,配置相關環境變量,上傳zookeeper壓縮包
    [zk_hom]# tar -zxvf apache-zookeeper-3.5.5-bin.tar.gz //解壓
    [zk_hom]# mkdir zkdata //新建一個數據持久化目錄
    [zk_hom]# cd conf //進入配置目錄
    [zk_hom/confg]# cp zoo_example.cfg zoo.cfg //複製配置文件樣本,並重命名未zoo.cfg
    編解zoo.cfg,將其中的dataDir = zk_home/zkdata
    [zk_hom/bin]# sh ./zkServer.sh start //啓動節點
    [zk_hom/bin]# sh ./zkServer.sh status //查看節點狀態服務器

    集羣部署

  • 各個節點上的準備工做同單機的同樣,都須要jdk,zookeeper壓縮包,同時要拷貝配置並配置數據持久化目錄,同時爲各節點新建持久化目錄。
  • 不一樣的是須要在各節點的zookeeper持久化目錄中新建一個名爲「myid」的文件,文件中各自寫上節點編號1~5。
  • 配置文件中須要追加集羣中其餘節點的訪問地址:
    【server.myid = ip:通訊端口:選舉端口】
    server.1 = 192.168.50.1:2181:3181
    server.2 = 192.168.50.2:2181:3181
    server.3 = 192.168.50.3:2181:3181
    server.4 = 192.168.50.4:2181:3181
    server.5 = 192.168.50.5:2181:3181
  • 啓動各個節點網絡

    應用管理

    bin/zkServer.sh start //開啓服務
    bin/zkServer.sh status //查看服務狀態
    bin/zkServer.sh stop //中止服務端
    bin/zkCli.sh -server 192.168.199.175:2181 //使用客戶端鏈接服務端數據結構

    客戶端命令

    應用場景

  1. 配置管理
    在咱們的應用中除了代碼外,還有一些就是各類配置。好比數據庫鏈接等。通常咱們都 是使用配置文件的方式,在代碼中引入這些配置文件。當咱們只有一種配置,只有一臺服務 器,而且不常常修改的時候,使用配置文件是一個很好的作法,可是若是咱們配置很是多, 有不少服務器都須要這個配置,這時使用配置文件就不是個好主意了。這個時候每每須要尋 找一種集中管理配置的方法,咱們在這個集中的地方修改了配置,全部對這個配置感興趣的 均可以得到變動。Zookeeper 就是這種服務,它使用 Zab 這種一致性協議來提供一致性。現 在有不少開源項目使用 Zookeeper 來維護配置,好比在 HBase 中,客戶端就是鏈接一個 Zookeeper,得到必要的 HBase 集羣的配置信息,而後才能夠進一步操做。還有在開源的消 息隊列 Kafka 中,也使用 Zookeeper來維護broker的信息。在 Alibaba開源的 SOA 框架Dubbo 中也普遍的使用 Zookeeper 管理一些配置來實現服務治理。
  2. 名稱服務
    名稱服務這個就很好理解了。好比爲了經過網絡訪問一個系統,咱們得知道對方的 IP 地址,可是 IP 地址對人很是不友好,這個時候咱們就須要使用域名來訪問。可是計算機是 不能是域名的。怎麼辦呢?若是咱們每臺機器裏都備有一份域名到 IP 地址的映射,這個倒 是能解決一部分問題,可是若是域名對應的 IP 發生變化了又該怎麼辦呢?因而咱們有了 DNS 這個東西。咱們只須要訪問一個你們熟知的(known)的點,它就會告訴你這個域名對應 的 IP 是什麼。在咱們的應用中也會存在不少這類問題,特別是在咱們的服務特別多的時候, 若是咱們在本地保存服務的地址的時候將很是不方便,可是若是咱們只須要訪問一個你們都 熟知的訪問點,這裏提供統一的入口,那麼維護起來將方便得多了。
  3. 分佈式鎖
    其實在第一篇文章中已經介紹了 Zookeeper 是一個分佈式協調服務。這樣咱們就能夠利 用 Zookeeper 來協調多個分佈式進程之間的活動。好比在一個分佈式環境中,爲了提升可靠 性,咱們的集羣的每臺服務器上都部署着一樣的服務。可是,一件事情若是集羣中的每一個服 務器都進行的話,那相互之間就要協調,編程起來將很是複雜。而若是咱們只讓一個服務進 行操做,那又存在單點。一般還有一種作法就是使用分佈式鎖,在某個時刻只讓一個服務去幹活,當這臺服務出問題的時候鎖釋放,當即 fail over 到另外的服務。這在不少分佈式系統 中都是這麼作,這種設計有一個更好聽的名字叫 Leader Election(leader 選舉)。好比 HBase 的 Master 就是採用這種機制。但要注意的是分佈式鎖跟同一個進程的鎖仍是有區別的,所 以使用的時候要比同一個進程裏的鎖更謹慎的使用。
  4. 集羣管理
    在分佈式的集羣中,常常會因爲各類緣由,好比硬件故障,軟件故障,網絡問題,有些 節點會進進出出。有新的節點加入進來,也有老的節點退出集羣。這個時候,集羣中其餘機 器須要感知到這種變化,而後根據這種變化作出對應的決策。好比咱們是一個分佈式存儲系 統,有一箇中央控制節點負責存儲的分配,當有新的存儲進來的時候咱們要根據如今集羣目 前的狀態來分配存儲節點。這個時候咱們就須要動態感知到集羣目前的狀態。還有,好比一 個分佈式的 SOA 架構中,服務是一個集羣提供的,當消費者訪問某個服務時,就須要採用 某種機制發現如今有哪些節點能夠提供該服務(這也稱之爲服務發現,好比 Alibaba 開源的 SOA 框架 Dubbo 就採用了 Zookeeper 做爲服務發現的底層機制)。還有開源的 Kafka 隊列就 採用了 Zookeeper 做爲 Cosnumer 的上下線管理。
  5. 負載均衡的集羣管理
相關文章
相關標籤/搜索