1 定義
ZooKeeper是Hadoop的開源子項目(Google Chubby的開源實現),它是一個針對大型分佈式系統的可靠協調系統,提供的功能包括:配置維護與同步、命名服務(在集羣所有機器裏生成唯一ID)、負載均衡、分佈式鎖、分佈式協調/同步(心跳檢測等)、組服務等。
Zookeeper的Fast Fail 和 Leader選舉特性大大增強了分佈式集羣的穩定和健壯性,並且解決了Master/Slave模式的單點故障重大隱患,這是越來越多的分佈式產品如HBase、Storm(流計算)、S4(流計算)等強依賴Zookeeper的原因。
開源ZK客戶端:ZkClient(功能較少)、Curator(推薦)。
官網:http://zookeeper.apache.org
2 架構
zookeeper集羣包含多臺Server,其中有且僅有一臺Server是leader,類似master/slave架構。
3 原理
3.1 ZK選舉ZAB協議
ZookeeperAtomic Broadcast,Zookeeper原子消息廣播協議,簡稱ZAB。
所有事務請求必須由一個全局唯一的服務器來協調處理,這樣的服務器被稱爲Leader服務器,而餘下的其它服務器則成爲Follower服務器。Leader服務器負責將一個客戶端事務請求(如創建節點等)轉換成一個事務Proposal(提議),並將該Proposal分發給集羣中所有的Follower服務器。之後Leader服務器需要等待所有Follower服務器的反饋,一旦超過半數的Follower服務器進行了正確的反饋後,那麼Leader就會再次向所有的Follower服務器分發Commit消息,要求其將前一個Proposal進行提交。
ZAB協議三個階段:
Ø 發現(Discovery),即選舉Leader的過程。
Ø 同步(Synchronization),選舉出新的Leader後,Follwer或Observer從Leader同步最新數據。
Ø 廣播,同步完成後,就可以接收客戶端新的事務請求,並進行消息廣播,實現數據在集羣節點的副本存儲。
3.2 服務器角色
Ø Leader
– 事務請求的唯一調度和處理者,保證集羣事務處理的順序性
– 集羣內部各服務器的調度者
Ø Follower
– 處理客戶端非事務請求,轉發事務請求給Leader服務器
– 參與事務請求Proposal的投票
– 參與Leader選舉投票
Ø Observer
– 處理客戶端非事務請求,轉發事務請求給Leader服務器
– 不參與任何形式的投票,包括選舉和事務投票(超過半數確認)
– 此角色存在通常是爲了提高集羣數據的讀性能
3.3 服務器狀態
Ø LOOKING
– 尋找Leader狀態
– 當服務器處此狀態時,表示當前沒有Leader,需要進入選舉流程
Ø FOLLOWING
– 跟隨者狀態,表明當前服務器角色是Follower
Ø OBSERVING
– 觀察者狀態,表明當前服務器角色是Observer
Ø LEADING
– 領導者狀態,表明當前服務器角色是Leader
org.apache.zookeeper.server.quorum.ServerState類維護以上四種狀態
3.4 集羣服務器間通訊
Ø 基於TCP協議
– 爲了避免重複創建兩個節點之間的tcp連接,zk按照myid數值方向來建立連接,即數值小的節點發起到數值大的節點的連接,比如id爲1的向id爲2的發起tcp連接
Ø 多端口
– 配置中第一個端口是通信和數據同步端口,默認是2888
– 第二個端口是投票端口,默認是3888
4 安裝
系統:CentOS 7.0。
版本:JDK 1.8.0_91,Hadoop2.7.3,Zookeeper 3.4.9。
4.1 下載安裝
http://mirrors.hust.edu.cn/apache/zookeeper/stable
解壓到合適位置即完成安裝。
4.2 配置
配置文件位於ZOOKEEPER_HOME/conf目錄下(zoo_sample.cfg)。
複製一份示例配置文件,改名爲zoo.cfg。
其中主要配置項含義:
Ø tickTime:心跳檢測的時間間隔(毫秒),缺省:2000。
Ø clientPort:其他應用(比如solr)訪問ZooKeeper的端口,缺省:2181。
Ø initLimit:初次同步的階段(followers連接到leader的階段),允許的時長(tick數量),缺省:10。
Ø syncLimit:允許。followers同步到ZooKeeper的時長(tick數量),缺省:5。
Ø dataDir:數據(比如所管理的配置文件)的存放路徑,初始時應該爲空。該目錄下需包含myid文件,存儲本服務器的服務器編號(1-255)。
Ø server.X:X是ensemble中一個服務器的id,後面指定該server的hostname、第一個端口號用於ZooKeeper之間的通信、第二個端口用於和其他應用之間的通信。
server.X示例:
server.1=nn:2888:3888,其中myid值應爲1,nn爲該服務器hostname,2888端口號是ZooKeeper服務之間通信的端口,3888是ZooKeeper與其他應用程序通信的端口。
4.2.1 配置文件示例
#The number of milliseconds of each tick
tickTime=2000
#The number of ticks that the initial
#synchronization phase can take
initLimit=10
#The number of ticks that can pass between
#sending a request and getting an acknowledgement
syncLimit=5
#the directory where the snapshot is stored.
#do not use /tmp for storage, /tmp here is just
#example sakes.
dataDir=/root/bigdata/zookeeper-3.4.9/dataDir
#the port at which the clients will connect
clientPort=2181
#the maximum number of client connections.
#increase this if you need to handle more clients
#maxClientCnxns=60
#
#Be sure to read the maintenance section of the
#administrator guide before turning on autopurge.
#
#http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
#The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
#Purge task interval in hours
#Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.1=nn:2888:3888
server.2=snn:2888:3888
server.3=dn01:2888:3888
server.4=dn02:2888:3888
4.3 啓動
在每個zookeeper節點bin目錄裏,運行命令啓動zookeeper服務器(默認載入zoo.cfg):
# ./zkServer.shstart
正常啓動後顯示:
ZooKeeperJMX enabled by default
Usingconfig: /root/bigdata/zookeeper-3.4.9/bin/../conf/zoo.cfg
Startingzookeeper ... STARTED
停止:
# ./zkServer.shstop
ZooKeeperJMX enabled by default
Usingconfig: /root/bigdata/zookeeper-3.4.9/bin/../conf/zoo.cfg
Stoppingzookeeper ... STOPPED
4.4 查看狀態
# ./zkServer.shstatus
ZooKeeperJMX enabled by default
Usingconfig: /root/bigdata/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode:leader
或
ZooKeeperJMX enabled by default
Usingconfig: /root/bigdata/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode:follower
4.5 客戶端連接
4.5.1 zkCli
# ./zkCli.sh -server 192.168.1.210:2181
4.5.2 Curator
5 常見問題
5.1 集羣啓動報服務器間連接失敗
如遇到connection failed、connection refused問題,請檢查防火牆是否關閉,基本是由於防火牆問題引起的。