一、Zookeeper介紹
1. 介紹Zookeeper之前先來介紹一下分布式
1.1 分布式主要是下面兩個方面:
1) 任務拆分
任務拆分指的是把傳統的單節點服務拆分成多個節點服務部署到不同的機器上對外提供服務。比如一個傳統服務有訂單+支付+物流等3個模塊,拆分成訂單系統、支付系統、物流系統3個服務。
2) 節點分工
如上面的服務拆分后,訂單系統、支付系統、物流系統各司其職
說明:
分布式解決高可用,高並發的。
集群解決的是高可用。
集群從物理上來定義,分布式一種工作方式。
例如:一個工作任務需要10個小時(單節點)
分布式:10台機器,任務只需要1個小時就能夠完成
集群:10台機器,任務還是10個小時。
1.2 分布式協作中的難點:
如果讓你設計一個分布式系統,你預見到什么問題?
1) 保證節點高可用(節點故障)
2) 數據的一致性
3) 通訊異常
4) 網絡分區
.......
2. Zookeeper簡介
Zookeeper就是用來解決分布式協作中的難點的
zookeeper是google的chubby項目開源實現。最早是hadoop的子項目
Zookeeper的使用場景:
小米米聊、淘寶Taokeeper其實是類zookeeper。
Kafka使用zookeeper。消息發布訂閱,其中zk就是用於檢測節點崩潰。實現主題的發現,並且保持主題的生產和消費狀態。
Hbase三段查找,Root-Region=》Meta Region=》Region(Table)。hbase的元數據信息放在HBase。HMaster掛掉,馬上要節點恢復。
Hadoop。NameNode(SecondaryNameNode),HA Hadoop。一般情況下一個簡單的hadoop集群,只有一個NameNode,如果NameNode掛掉,hadoop集群不可用。HA Haoop里面就要用到zk。
3. Zookeeper解決哪些問題
3.1 Master節點管理
解決的問題:Master高可用(掛掉以后,誰來負責工作),保證唯一。
3.2 配置文件管理
解決的問題:統一把配置文件存放zk,由ZK統一分發修改的內容到各台機器。
3.3 發布與訂閱
發布者(producer)將數據發布到zk節點上,供訂閱者(consumer)動態獲取
3.4 分布式鎖
分布式環境訪問同一個資源,由第三方配鎖實現。
解決的問題:由zk統一進行協調,保證數據的一致性。
3.5 集群的管理
Worker集群監控。保證主數據和備份數據的一致
二、Zookeeper安裝配置
環境准備:
一台安裝有jdk的虛擬機:192.168.152.130
1. 安裝
1.1.下載
cd /software
wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz
1.2.解壓
tar -zxvf zookeeper-3.4.6.tar.gz
2. 配置
說明:這里配置的是偽分布式的zookeeper
注意:配置之前一定要在/etc/hosts里面配置主機映射,否則會報錯誤:
ERROR [master:3890:QuorumCnxManager$Listener@517] - Exception while listening
java.net.SocketException: Unresolved address
vim /etc/hosts

2.1 先建立zookeeper的三個數據目錄
mkdir -p /zookeeper/zk1
mkdir -p /zookeeper/zk2
mkdir -p /zookeeper/zk3

2.2 查看zookeeper的配置文件(已刪掉多余的配置和注釋)
vim zoo_sample.cfg
tickTime=2000 #session的會話時間 以ms為單位
initLimit=10 #服務器啟動以后,master和slave通訊的時間
syncLimit=5 #master和slave之間的心跳檢測時間,檢測slave是否存活
dataDir=/tmp/zookeeper #保存zk的快照和數據
clientPort=2181 #客戶端訪問zk的端口
2.3 復制zoo_sample.cfg為zoo1.cfg添加如下配置
cp zoo_sample.cfg zoo1.cfg
vim zoo1.cfg
配置:
#session的會話時間 以ms為單位
tickTime=2000
#服務器啟動以后,master和slave通訊的時間
initLimit=10
#master和slave之間的心跳檢測時間,檢測slave是否存活
syncLimit=5
#(這個目錄可以自行指定)
dataDir=/zookeeper/zk1
#客戶端訪問zk的端口
clientPort=2181
#master對應於前面在hosts里面配置的主機映射 2888是數據同步和消息傳遞端口,3888是選舉端口 server.1=master:2888:3888 #master對應於前面在hosts里面配置的主機映射 2889是數據同步和消息傳遞端口,3889是選舉端口
server.2=master:2889:3889
#master對應於前面在hosts里面配置的主機映射 2890是數據同步和消息傳遞端口,3890是選舉端口
server.3=master:2890:3890
2.4 復制zoo1.cfg為zoo2.cfg添加如下配置
cp zoo1.cfg zoo2.cfg
vim zoo2.cfg
#session的會話時間 以ms為單位 tickTime=2000 #服務器啟動以后,master和slave通訊的時間 initLimit=10 #master和slave之間的心跳檢測時間,檢測slave是否存活 syncLimit=5 #(這個目錄可以自行指定) dataDir=/zookeeper/zk2 #客戶端訪問zk的端口 clientPort=2182 #master對應於前面在hosts里面配置的主機映射 2888是數據同步和消息傳遞端口,3888是選舉端口 server.1=master:2888:3888 #master對應於前面在hosts里面配置的主機映射 2889是數據同步和消息傳遞端口,3889是選舉端口
server.2=master:2889:3889
#master對應於前面在hosts里面配置的主機映射 2890是數據同步和消息傳遞端口,3890是選舉端口
server.3=master:2890:3890
2.5 復制zoo1.cfg為zoo3.cfg添加如下配置
cp zoo1.cfg zoo3.cfg
vim zoo3.cfg
#session的會話時間 以ms為單位
tickTime=2000
#服務器啟動以后,master和slave通訊的時間
initLimit=10
#master和slave之間的心跳檢測時間,檢測slave是否存活
syncLimit=5
#(這個目錄可以自行指定)
dataDir=/zookeeper/zk3
#客戶端訪問zk的端口
clientPort=2183
#master對應於前面在hosts里面配置的主機映射 2888是數據同步和消息傳遞端口,3888是選舉端口 server.1=master:2888:3888 #master對應於前面在hosts里面配置的主機映射 2889是數據同步和消息傳遞端口,3889是選舉端口
server.2=master:2889:3889
#master對應於前面在hosts里面配置的主機映射 2890是數據同步和消息傳遞端口,3890是選舉端口
server.3=master:2890:3890
2.6 手動建立myid文件且指定在zk數據目錄,也就是dataDir指定的路徑(不管真分布還是偽分布都需要指定)
echo 1 >> /zookeeper/zk1/myid
echo 2 >> /zookeeper/zk2/myid
echo 3 >> /zookeeper/zk3/myid
說明:
myid文件內容分別為1,2,3對應於zk配置文件的server.1,server.2,server.3
2.7 測試zookeeper分布式是否搭建成功
分別啟動三個zookeeper
cd /software/zookeeper-3.4.6/bin/
./zkServer.sh start /software/zookeeper-3.4.6/conf/zoo1.cfg
./zkServer.sh start /software/zookeeper-3.4.6/conf/zoo2.cfg
./zkServer.sh start /software/zookeeper-3.4.6/conf/zoo3.cfg

查看3個zookeeper的狀態
cd /software/zookeeper-3.4.6/bin/
/zkServer.sh status /software/zookeeper-3.4.6/conf/zoo1.cfg
/zkServer.sh status /software/zookeeper-3.4.6/conf/zoo2.cfg
/zkServer.sh status /software/zookeeper-3.4.6/conf/zoo3.cfg

可以看到第2個zookeeper是leader,第1個和第3個為follower,到此zookeeper分布式搭建完成!!!
2.8 Zookeeper常用命令
啟動:
./zkServer.sh start /software/zookeeper-3.4.6/conf/zoo1.cfg
./zkServer.sh start /software/zookeeper-3.4.6/conf/zoo2.cfg
./zkServer.sh start /software/zookeeper-3.4.6/conf/zoo3.cfg
停止:
./zkServer.sh stop /software/zookeeper-3.4.6/conf/zoo1.cfg
./zkServer.sh stop /software/zookeeper-3.4.6/conf/zoo2.cfg
./zkServer.sh stop /software/zookeeper-3.4.6/conf/zoo3.cfg
查看狀態:
/zkServer.sh status /software/zookeeper-3.4.6/conf/zoo1.cfg
/zkServer.sh status /software/zookeeper-3.4.6/conf/zoo2.cfg
/zkServer.sh status /software/zookeeper-3.4.6/conf/zoo3.cfg
2.9 Zookeeper真分布式部署在master、slave1、slave2 三台不同的服務器上
server1..../conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/zookeeper/zk
clientPort=2181
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888
server2..../conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/zookeeper/zk
clientPort=2181
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888
server3..../conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/zookeeper/zk
clientPort=2181
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888
注意:
真分布必須是奇數台,因為必須滿足n/2+1=m,m必須大於部署zk機器數的一半(n/2)可用才認為集群可用,而且奇數台更節省資源
2/2+1=2 一台不能壞
3/2+1=2 可以壞掉一台
4/2+1=3 只能壞一台
5/2+1=3 可以壞2台
三、ZK Shell的使用
1. 連接zk
zkCli.sh [-server ip:port]
示例:
連接到master(127.0.0.1 master)這台機器上2181的zookeeper
./zkCli.sh -server master 2181

2. 列出zk中的節點
ls、ls2
示例:

3. 創建節點
create [-s] [-e] path data acl
說明:
zk的節點分為兩種:臨時節點(隨着zk session消亡而自動刪除)、持久節點(一直存在)
-s: 順序節點
-e: 臨時節點
acl:訪問權限控制
示例:
3.1 創建一個zk-test的節點,數據是123 不帶-s 、-e默認是持久節點
create /zk-test "123"

3.2 創建順序節點
create -s /zk-test “test123”

多次執行創建順序節點的命令,可以看到zookeeper的內部會對順序節點的名稱進行自增控制

3.3 創建臨時節點
create -e /zk-test123 "test1234"

說明:
臨時節點依賴於順序節點,臨時節點下不能再創建臨時節點,順序節點下才可以創建臨時節點
3.4 創建子節點test
create /zk-test ""
create /zk-test/test "1"
ls /zk-test/test

4. 刪除節點命令
delete
示例:
刪除節點zk-test,如果zk-test下面還有子節點得先刪除子節點,才能刪除zk-test
delete /zk-test/test
delete /zk-test
遞歸刪除一個znode
rmr path
示例:
刪除zk-test及其下面的子節點
rmr /zk-test
5. 獲取節點信息
get
示例:
create /zk-123 “abc”
get /zk-123

結果說明:
結果
cZxid = #創建節點時zk內部自己分配的id
Ctime = #創建節點的時間
mZxid = #修改的id
mtime = 修改的時間
pZxid = 子節點最后一次被修改的id
cVersion = 0 #擁有的子節點被改的話,該值隨着改變
dataVersion = 0 #數據版本
aclVersion = 0 # 訪問控制權限的版本
ephemeralOwner = 0X0 #臨時節點還是持久節點 臨時節點值不為0(值為當前會話id),持久節點值永遠為0
dataLength = 3 #數據長度
numChildren = 0 #子節點個數
6. 更新節點數據
set /zk-123 “d”

7. 連接到指定節點
connect host:port
示例:
連接到2181
connect master:2181
連接到2182
connect master:2182
連接到2183
connect master:2183
說明:
這個命令是在已經連接到zookeeper之后,在里面切換到其他zookeeper時使用

8. 設置配額
配額:給某個目錄指定多少存儲空間或者允許創建多少個節點
setquota -n|-b val path
參數說明:
n 指定可以設置多少個子節點
b 指定可以設置多大空間(byte)
示例:
setquota -n 5 /zk-123
create /zk-123/1 1
create /zk-123/2 2
create /zk-123/3 3
create /zk-123/4 4
create /zk-123/5 5
create /zk-123/6 6
說明:
對於配額不是硬性的提示,超過配額還是可以繼續創建,只不過在日志里面有提示
配額的用途:
限制子節點的創建個數和分配空間的大小,如指定某個session有多少空間可以用
9. 查看配額
listquota path
10. 查看節點的狀態
stat path
示例:
查看節點zk-123的狀態
stat /zk-123

