顧名思義 zookeeper 就是動物園管理員,他是用來管 hadoop(大象)、Hive(蜜蜂)、pig(小 豬)的管理員, Apache Hbase 和 Apache Solr 的分布式集群都用到了 zookeeper;Zookeeper: 是一個分布式的、開源的程式協調服務,是 hadoop 專案下的一個子專案,他提供的主要功 能包括:配置管理、名稱服務、分布式鎖、集群管理,
功能特性
- 最終一致性:client 不論連接到哪個 Server,展示給它都是同一個視圖,這是 zookeeper 最重要的性能,
- 可靠性:具有簡單、健壯、良好的性能,如果訊息 m 被到一臺服務器接受,那么它 將被所有的服務器接受,
- 實時性:Zookeeper 保證客戶端將在一個時間間隔范圍內獲得服務器的更新資訊,或 者服務器失效的資訊,但由于網路延時等原因,Zookeeper 不能保證兩個客戶端能同時得到 剛更新的資料,如果需要最新資料,應該在讀資料之前呼叫 sync()介面,
- 等待無關(wait-free):慢的或者失效的 client 不得干預快速的 client 的請求,使得每 個 client 都能有效的等待,
- 原子性:更新只能成功或者失敗,沒有中間狀態,
- 順序性:包括全域有序和偏序兩種:全域有序是指如果在一臺服務器上訊息 a 在訊息 b 前發布,則在所有 Server 上訊息 a 都將在訊息 b 前被發布;偏序是指如果一個訊息 b 在消 息 a 后被同一個發送者發布,a 必將排在 b 前面,
行程角色
- leader:由集群成員投票選舉出來的領導者,負責處理外部發到集群的讀寫請求,處理寫請求時會發起投票,只有集群內超過半數節點通過后寫操作才會被通過,
- follower:負責處理都請求并回傳結果,如果接收到寫請求則將之轉發給leader,還要負責leader選舉時的投票,
- observer:可以理解為沒有選舉權的follower,只負責處理業務,時為了提高集群吞吐率,同時又能保證集群快速完成選舉而引進的機制,
機制
- 集群的兩種模式
- 恢復模式:集群的一種非穩定狀態,集群不能處理外部請求;集群啟動或遇到leader崩潰時,集群進入恢復模式,在本模式中選舉leader,leader選舉完成后其他節點與leader進行資料同步,當過半節點完成同步后恢復模式結束,進入廣播模式,
- 廣播模式:集群的穩定狀態,集群能正常的處理外部請求;此時若有新節點加入,新節點會自動從leader同步資料,
- 集群啟動程序:
- leader選舉原則
- 集群中只有超過半數的節點處于正常狀態,集群才能穩定,才能處理外部請求,
- 集群正常作業之前myid小的節點會優先給myid大的節點投票,直到選出leader為止,
- 選出leader之前,集群所有節點都處于looking狀態,選舉成功后,除leader節點外,其余節點的狀態由looking變為following,角色也成為了follower,
- leader選舉程序
- 假設集群有5個節點,myid分別為15,假設集群第一次啟動,所有節點都沒有歷史資料,啟動順序15,由集群節點數量可知,至少要有3個節點正常,集群才能穩定作業,
- 節點1啟動,其初始狀態為looking,發起一輪選舉,節點1投自己一票,由于不過半,本輪選舉無法完成,節點1仍然保持looking狀態,
- 節點2啟動,其初始狀態為looking,它也發起一輪選舉,節點2投自己一票;節點1也參與進本輪投票,打算給自己投一票,但是發現節點2的myid比自己的大,就改投節點2一票;本輪投票過后節點1得0票,節點2得2票,由于節點2的得票數不過半,所以本輪選舉未能完成;節點1、2都保持looking狀態,
- 節點3啟動,其初始狀態為looking,它也發起一輪選舉,且節點3先投自己一票;節點1、2也都參與進本輪投票中來,打算投自己一票,發現本輪中節點3的myid大于自己的,所以節點1、2都轉投節點3一票;此時節點3就識訓了3票,超過了集群節點的半數,節點3率先當選,并從looking狀態變為leading狀態,節點1、2的狀態變為following,
- 節點4啟動,其初始狀態為looking,它也發起一輪選舉;此時由于節點1、2處于following狀態,這兩個節點就不參與本輪選舉,節點4本打算投自己一票,但是發現節點3已進入leading狀態,且票數已經過半,此時節點4就會將自己的一票轉投給節點3,節點4未收到投票,狀態由looking變為following,
- 節點5的啟動程序與節點4一樣,最終未獲得投票,也處于following狀態,
- 最終節點3成為leader,節點1、2、4、5成為follower,
- leader選舉原則
- 崩潰恢復程序:當leader崩潰后,集群中的其他follower節點會重新變為looking狀態,重新進行leader選舉,選舉程序同啟動時的leader選舉一樣,
- 訊息廣播演算法:
- 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位是每個事務特定的標識,相當于皇帝發布的號令,對一個皇帝來說這個編號也是全域自增的,
資料結構
- Znode
在 Zookeeper 中,znode 是一個跟 Unix 檔案系統路徑相似的節點,可以往這個節點存盤 或獲取資料, Zookeeper 底層是一套資料結構,這個存盤結構是一個樹形結構,其上的每一個節點, 我們稱之為“znode” zookeeper 中的資料是按照“樹”結構進行存盤的,而且 znode 節點還分為 4 中不同的類 型, 每一個 znode 默認能夠存盤 1MB 的資料(對于記錄狀態性質的資料來說,夠了) 可以使用 zkCli 命令,登錄到 zookeeper 上,并通過 ls、create、delete、get、set 等命令 操作這些 znode 節點 - Znode 節點型別
- PERSISTENT 持久化節點: 所謂持久節點,是指在節點創建后,就一直存在,直到 有洗掉操作來主動清除這個節點,否則不會因為創建該節點的客戶端會話失效而消失,
- PERSISTENT_SEQUENTIAL 持久順序節點:這類節點的基本特性和上面的節點類 型是一致的,額外的特性是,在 ZK 中,每個父節點會為他的第一級子節點維護一份時序, 會記錄每個子節點創建的先后順序,基于這個特性,在創建子節點的時候,可以設定這個屬 性,那么在創建節點程序中,ZK 會自動為給定節點名加上一個數字后綴,作為新的節點名, 這個數字后綴的范圍是整型的最大值, 在創建節點的時候只需要傳入節點 “/test_”,這樣 之后,zookeeper 自動會給”test_”后面補充數字,
- EPHEMERAL 臨時節點:和持久節點不同的是,臨時節點的生命周期和客戶端會 話系結,也就是說,如果客戶端會話失效,那么這個節點就會自動被清除掉,注意,這里提 到的是會話失效,而非連接斷開,另外,在臨時節點下面不能創建子節點, 這里還要注意一件事,就是當你客戶端會話失效后,所產生的節點也不是一下子就消失 了,也要過一段時間,大概是 10 秒以內,可以試一下,本機操作生成節點,在服務器端用 命令來查看當前的節點數目,你會發現客戶端已經 stop,但是產生的節點還在,
- EPHEMERAL_SEQUENTIAL 臨時自動編號節點:此節點是屬于臨時節點,不過帶 有順序,客戶端會話結束節點就消失,
目錄結構
- bin:放置運行腳本和工具腳本,如果是 Linux 環境還會有有 zookeeper 的運 行日志 zookeeper.out
- conf:zookeeper 默認讀取配置的目錄,里面會有默認的組態檔
- contrib:zookeeper 的拓展功能
- dist-maven:zookeeper的 maven 打包目錄
- docs:zookeeper 相關的檔案
- lib:zookeeper 核心的 jar
- recipes:zookeeper 分布式相關的 jar 包
- 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 //使用客戶端連接服務端
客戶端命令
應用場景
- 配置管理
在我們的應用中除了代碼外,還有一些就是各種配置,比如資料庫連接等,一般我們都 是使用組態檔的方式,在代碼中引入這些組態檔,當我們只有一種配置,只有一臺服務 器,并且不經常修改的時候,使用組態檔是一個很好的做法,但是如果我們配置非常多, 有很多服務器都需要這個配置,這時使用組態檔就不是個好主意了,這個時候往往需要尋 找一種集中管理配置的方法,我們在這個集中的地方修改了配置,所有對這個配置感興趣的 都可以獲得變更,Zookeeper 就是這種服務,它使用 Zab 這種一致性協議來提供一致性,現 在有很多開源專案使用 Zookeeper 來維護配置,比如在 HBase 中,客戶端就是連接一個 Zookeeper,獲得必要的 HBase 集群的配置資訊,然后才可以進一步操作,還有在開源的消 息佇列 Kafka 中,也使用 Zookeeper來維護broker的資訊,在 Alibaba開源的 SOA 框架Dubbo 中也廣泛的使用 Zookeeper 管理一些配置來實作服務治理, - 名稱服務
名稱服務這個就很好理解了,比如為了通過網路訪問一個系統,我們得知道對方的 IP 地址,但是 IP 地址對人非常不友好,這個時候我們就需要使用域名來訪問,但是計算機是 不能是域名的,怎么辦呢?如果我們每臺機器里都備有一份域名到 IP 地址的映射,這個倒 是能解決一部分問題,但是如果域名對應的 IP 發生變化了又該怎么辦呢?于是我們有了 DNS 這個東西,我們只需要訪問一個大家熟知的(known)的點,它就會告訴你這個域名對應 的 IP 是什么,在我們的應用中也會存在很多這類問題,特別是在我們的服務特別多的時候, 如果我們在本地保存服務的地址的時候將非常不方便,但是如果我們只需要訪問一個大家都 熟知的訪問點,這里提供統一的入口,那么維護起來將方便得多了, - 分布式鎖
其實在第一篇文章中已經介紹了 Zookeeper 是一個分布式協調服務,這樣我們就可以利 用 Zookeeper 來協調多個分布式行程之間的活動,比如在一個分布式環境中,為了提高可靠 性,我們的集群的每臺服務器上都部署著同樣的服務,但是,一件事情如果集群中的每個服 務器都進行的話,那相互之間就要協調,編程起來將非常復雜,而如果我們只讓一個服務進 行操作,那又存在單點,通常還有一種做法就是使用分布式鎖,在某個時刻只讓一個服務去干活,當這臺服務出問題的時候鎖釋放,立即 fail over 到另外的服務,這在很多分布式系統 中都是這么做,這種設計有一個更好聽的名字叫 Leader Election(leader 選舉),比如 HBase 的 Master 就是采用這種機制,但要注意的是分布式鎖跟同一個行程的鎖還是有區別的,所 以使用的時候要比同一個行程里的鎖更謹慎的使用, - 集群管理
在分布式的集群中,經常會由于各種原因,比如硬體故障,軟體故障,網路問題,有些 節點會進進出出,有新的節點加入進來,也有老的節點退出集群,這個時候,集群中其他機 器需要感知到這種變化,然后根據這種變化做出對應的決策,比如我們是一個分布式存盤系 統,有一個中央控制節點負責存盤的分配,當有新的存盤進來的時候我們要根據現在集群目 前的狀態來分配存盤節點,這個時候我們就需要動態感知到集群目前的狀態,還有,比如一 個分布式的 SOA 架構中,服務是一個集群提供的,當消費者訪問某個服務時,就需要采用 某種機制發現現在有哪些節點可以提供該服務(這也稱之為服務發現,比如 Alibaba 開源的 SOA 框架 Dubbo 就采用了 Zookeeper 作為服務發現的底層機制),還有開源的 Kafka 佇列就 采用了 Zookeeper 作為 Cosnumer 的上下線管理, - 負載均衡的集群管理
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/29376.html
標籤:大數據
下一篇:Yarn架構
