ZooKeeper是一個分佈式的,開放源碼的分佈式應用程序協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個爲分佈式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分佈式同步、組服務等。java
ZooKeeper的目標就是封裝好複雜易出錯的關鍵服務,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。linux
ZooKeeper包含一個簡單的原語集提供Java和C的接口。算法
ZooKeeper代碼版本中,提供了分佈式獨享鎖、選舉、隊列的接口,代碼在zookeeper-3.4.3\src\recipes。其中分佈鎖和隊列有Java和C兩個版本,選舉只有Java版本。apache
主要做用是用來解決分佈式應用中常常遇到的一些數據管理問題,如集羣管理、統一命名管理、分佈式配置管理、分佈式消息隊列、分佈式鎖、分佈式通知協調vim
官方網站:https://zookeeper.apache.org/segmentfault
zk的集羣中有一個Leader,有一個或多個follower,它們之間是相互通訊的,而後還存在一個客戶端用來訪問zk服務器。api
服務器端具備fast fail特性,一旦主故障後,會選舉從成爲新的主,主從模式是目前最多見的模式。服務器
zookeeper名字空間由節點NODE構成,相似於文件系統,其中各個節點至關於目錄和文件,經過路徑做爲惟一標識,與文件系統不一樣的是,每一個節點具備與之對應的數據內容,同時也能夠具備子節點,它用來存儲協調數據,如狀態、配置、位置信息、每一個節點存儲的數據量很小,KB級別.jvm
watches介紹分佈式
zk對節點的增、刪、改、查均可以觸發監聽
watch事件是一次性觸發器,當它監視的數據發生變化時,通知設置了該客戶端
四臺服務器
zk-001 10.0.0.8zk-002 10.0.0.9
zk-003 10.0.0.10
zk-client 10.0.0.100
下載安裝JDK環境
tar zxf jdk-8u60-linux-x64.tar.gz mv jdk1.8.0_60 /usr/local/jdk export JAVA_HOME=/usr/local/jdk export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export PATH=$JAVA_HOME/bin:$PATH source /etc/profile java -version [root@zk-001 ~]# java -version java version "1.8.0_60" Java(TM) SE Runtime Environment (build 1.8.0_60-b27) Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
下載安裝zookeeper
wget http://www.apache.org/dist/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz tar zxf zookeeper-3.4.6.tar.gz mv zookeeper-3.4.6 /usr/local/zookeeper [root@zk-001 ~]# cd /usr/local/zookeeper/
配置環境變量
export ZOOKEEPER_HOME=/usr/local/zookeeper export PATH=$ZOOKEEPER_HOME/bin:$PATH source /etc/profile
三種配置模式
一、僞分佈模式二、徹底分佈式
三、獨立模式
獨立模式配置
[root@zk-001 zookeeper]# cd conf/ [root@zk-001 conf]# ll total 12 -rw-rw-r-- 1 1000 1000 535 Feb 20 2014 configuration.xsl -rw-rw-r-- 1 1000 1000 2161 Feb 20 2014 log4j.properties -rw-rw-r-- 1 1000 1000 922 Feb 20 2014 zoo_sample.cfg [root@zk-001 conf]# cp zoo_sample.cfg zoo.cfg [root@zk-001 conf]#vim zoo.cfg # The number of milliseconds of each tick tickTime=2000 **#心跳檢查週期(單位毫秒)** # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=/tmp/zookeeper **#存放數據目錄** # the port at which the clients will connect clientPort=2181 **#供客戶端鏈接的端口**
集羣模式配置
tickTime=2000
initLimit=10
syncLimit=5
//server.n=host:port1:port2
數字N必須是myid中的值,Myid文件位於dataDIR目錄下,只能是一個n值
//port1:leader端口,做爲leader時,供follower鏈接的端口
//port2:選舉端口,選舉leader時,供follower鏈接的端口
server.1=s1:2888:3888
server.2=s2:2888:3888
server.3=s3:2888:3888
zk處理集羣故障的算法是2n+1,最好在奇數機器數佈署,若是同臺服務器配置多實例就要注意端口衝突問題,能夠寫成以下
server.1=s1:2888:3888
server.2=s2:2889:3889
server.3=s3:2887:3887
配置過程以下
配置hosts文件
vim /etc/hosts 10.0.0.8 zk-001 10.0.0.9 zk-002 10.0.0.10 zk-003
配置各服務器配置文件
[root@zk-001 conf]# mkdir /tmp/zookeeper [root@zk-001 conf]# cd /tmp/zookeeper/ [root@zk-001 zookeeper]# echo 8 >myid [root@zk-001 conf]# egrep -v "^#|^$" zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/tmp/zookeeper clientPort=2181 server.8=zk-001:2888:3888 server.9=zk-002:2888:3888 server.10=zk-003:2888:3888 [root@zk-002 ~]# mkdir /tmp/zookeeper [root@zk-002 ~]# cd /tmp/zookeeper/ [root@zk-002 zookeeper]# echo 9 >myid [root@zk-002 zookeeper]# ll total 4 -rw-r--r-- 1 root root 2 May 13 15:51 myid [root@zk-002 zookeeper]# cd /usr/local/zookeeper/conf/ [root@zk-002 conf]# cp zoo_sample.cfg zoo.cfg [root@zk-002 conf]# vim zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/tmp/zookeeper clientPort=2181 server.8=zk-001:2888:3888 server.9=zk-002:2888:3888 server.10=zk-003:2888:3888 [root@zk-003 ~]# mkdir /tmp/zookeeper [root@zk-003 ~]# cd /tmp/zookeeper/ [root@zk-003 zookeeper]# echo 10 >myid [root@zk-003 zookeeper]# cd /usr/local/zookeeper/conf/ [root@zk-003 conf]# cp zoo_sample.cfg zoo.cfg [root@zk-003 conf]# vim zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/tmp/zookeeper clientPort=2181 server.8=zk-001:2888:3888 server.9=zk-002:2888:3888 server.10=zk-003:2888:3888
啓動服務
[root@zk-001 bin]# zkServer.sh start JMX enabled by default Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg Starting zookeeper ... STARTED [root@zk-002 bin]# zkServer.sh start JMX enabled by default Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg Starting zookeeper ... STARTED [root@zk-003 bin]# zkServer.sh start JMX enabled by default Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg Starting zookeeper ... STARTED
查看狀態
[root@zk-001 conf]# zkServer.sh status JMX enabled by default Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg Mode: follower [root@zk-002 conf]# zkServer.sh status JMX enabled by default Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg Mode: follower [root@zk-003 conf]# zkServer.sh status JMX enabled by default Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg Mode: leader #能夠看出已經選舉leader出來了,代表配置是正確的
測試leader故障後切換狀況
[root@zk-003 conf]# jps 2694 Jps 2430 QuorumPeerMain [root@zk-003 conf]# kill 2430 [root@zk-003 conf]# jps 2724 Jps [root@zk-002 conf]# zkServer.sh status JMX enabled by default Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg Mode: follower [root@zk-001 conf]# zkServer.sh status JMX enabled by default Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg Mode: leader 能夠看出zk-001這臺服務器被選舉成新的leader了
conf 配置信息cons 鏈接信息
dump 未處理會話節點
envi 環境信息
reqs 未處理請求
stat 統計信息
wchs 服務器watch的詳細信息
wchp 列出指定路徑下服務器信息
[root@zk-003 ~]# echo conf | nc 10.0.0.8 2181 clientPort=2181 dataDir=/tmp/zookeeper/version-2 dataLogDir=/tmp/zookeeper/version-2 tickTime=2000 maxClientCnxns=60 minSessionTimeout=4000 maxSessionTimeout=40000 serverId=8 initLimit=10 syncLimit=5 electionAlg=3 electionPort=3888 quorumPort=2888 peerType=0 [root@zk-003 ~]# echo envi | nc 10.0.0.8 2181 Environment: zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT host.name=zk-001 java.version=1.8.0\_121 java.vendor=Oracle Corporation java.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el6_8.x86_64/jre java.class.path=/usr/local/zookeeper/bin/../build/classes:/usr/local/zookeeper/bin/../build/lib/*.jar:/usr/local/zookeeper/bin/../lib/slf4j-log4j12-1.6.1.jar:/usr/local/zookeeper/bin/../lib/slf4j-api-1.6.1.jar:/usr/local/zookeeper/bin/../lib/netty-3.7.0.Final.jar:/usr/local/zookeeper/bin/../lib/log4j-1.2.16.jar:/usr/local/zookeeper/bin/../lib/jline-0.9.94.jar:/usr/local/zookeeper/bin/../zookeeper-3.4.6.jar:/usr/local/zookeeper/bin/../src/java/lib/*.jar:/usr/local/zookeeper/bin/../conf: java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib java.io.tmpdir=/tmp java.compiler=<NA> os.name=Linux os.arch=amd64 os.version=2.6.32-504.el6.x86_64 user.name=root user.home=/root user.dir=/usr/local/zookeeper/conf [root@zk-003 ~]# echo stat | nc 10.0.0.8 2181 Zookeeper version: 3.4.6-1569965, built on 02/20/2014 09:09 GMT Clients: /10.0.0.10:41192[0](queued=0,recved=1,sent=0) Latency min/avg/max: 0/0/0 Received: 4 Sent: 3 Connections: 1 Outstanding: 0 Zxid: 0x200000000 Mode: leader Node count: 4
經過zkCli.sh 鏈接服務器
zkCli.sh -server zk-001:2181 -server 10.0.0.9:2181 [root@zk-001 ~]# zkCli.sh -server zk-002:2181 Connecting to zk-002:2181 WATCHER:: WatchedEvent state:SyncConnected type:None path:null [zk: zk-002:2181(CONNECTED) 0] h **##幫助命令** ZooKeeper -server host:port cmd args stat path [watch] set path data [version] ls path [watch] delquota [-n|-b] path ls2 path [watch] setAcl path acl setquota -n|-b val path history redo cmdno printwatches on|off delete path [version] sync path listquota path rmr path get path [watch] create [-s] [-e] path data acl addauth scheme auth quit getAcl path close connect host:port [zk: zk-002:2181(CONNECTED) 1] ls / #列出目錄下內容 [zookeeper] [zk: zk-002:2181(CONNECTED) 2] ls /zookeeper [quota] [zk: zk-002:2181(CONNECTED) 3] ls /zookeeper/quota [] [zk: zk-002:2181(CONNECTED) 4] create /root testfile #建立目錄及數據 Created /root [zk: zk-002:2181(CONNECTED)5]get /root **#獲取數據** testfile cZxid = 0x200000002 ctime = Sat May 13 20:09:52 CST 2017 mZxid = 0x200000002 mtime = Sat May 13 20:09:52 CST 2017 pZxid = 0x200000002 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 8 numChildren = 0 [zk: zk-002:2181(CONNECTED) 6] set /root testfile-001 cZxid = 0x200000002 ctime = Sat May 13 20:09:52 CST 2017 mZxid = 0x200000003 mtime = Sat May 13 21:04:17 CST 2017 pZxid = 0x200000002 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 12 numChildren = 0 #須要注意的是ZK是不能一次建立多級節點的 [zk: zk-002:2181(CONNECTED) 7] create /root/s1/s1-1 [zk: zk-002:2181(CONNECTED) 8] ls /root **#提示是空** [] [zk: zk-002:2181(CONNECTED) 9] create /root/s1 s1-data Created /root/s1 [zk: zk-002:2181(CONNECTED) 10] create /root/s2 s2-data Created /root/s2 [zk: zk-002:2181(CONNECTED) 11] create /root/s3 s3-data Created /root/s3 [zk: zk-002:2181(CONNECTED) 13] ls /root [s3, s1, s2] #查看狀態 [zk: zk-002:2181(CONNECTED) 14] stat /root cZxid = 0x200000002 ctime = Sat May 13 20:09:52 CST 2017 mZxid = 0x200000003 mtime = Sat May 13 21:04:17 CST 2017 pZxid = 0x200000006 cversion = 3 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 12 numChildren = 3 #刪除目錄 [zk: zk-002:2181(CONNECTED) 15] delete /root/s3 [zk: zk-002:2181(CONNECTED) 16] ls /root [s1, s2] #斷開鏈接 [zk: zk-002:2181(CONNECTED) 17] close 2017-05-13 21:13:00,603 [myid:] - INFO[main:ZooKeeper@684] - Session: 0x95c0122efa50000 closed 2017-05-13 21:13:00,604 [myid:] - INFO[main-EventThread:ClientCnxn$EventThread@512] - EventThread shut down #從新鏈接 因爲ZK服務器間的數據是一致的,所以此次我鏈接其它服務器 [zk: zk-002:2181(CLOSED) 18] connect zk-001:2181 [zk: zk-001:2181(CONNECTED) 19] get /root testfile-001 cZxid = 0x200000002 ctime = Sat May 13 20:09:52 CST 2017 mZxid = 0x200000003 mtime = Sat May 13 21:04:17 CST 2017 pZxid = 0x200000007 cversion = 4 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 12 numChildren = 2 [zk: zk-001:2181(CONNECTED) 20] get /root/s1 s1-data cZxid = 0x200000004 ctime = Sat May 13 21:07:42 CST 2017 mZxid = 0x200000004 mtime = Sat May 13 21:07:42 CST 2017 pZxid = 0x200000004 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 7 numChildren = 0
若有錯誤或其它問題,歡迎小夥伴留言評論、指正。若有幫助,歡迎點贊+轉發分享。
歡迎你們關注民工哥的公衆號:民工哥技術之路