1. 程式人生 > >配置 Zookeeper 集群

配置 Zookeeper 集群

默認 loop 網絡 none port nod 5.7 客戶端 link

一、Zookeeper原理簡介
ZooKeeper是一個開放源碼的分布式應用程序協調服務,它包含一個簡單的原語集,分布式應用程序可以基於它實現同步服務,配置維護和命名服務等。

Zookeeper設計目的
最終一致性:client不論連接到那個Server,展示給它的都是同一個視圖。
可靠性:具有簡單、健壯、良好的性能、如果消息m被到一臺服務器接收,那麽消息m將被所有服務器接收。
實時性:Zookeeper保證客戶端將在一個時間間隔範圍內獲得服務器的更新信息,或者服務器失效的信息。但由於網絡延時等原因,Zookeeper不能保證兩個客戶端能同時得到剛更新的數據,如果需要最新數據,應該在讀數據之前調用sync()接口。

等待無關(wait-free):慢的或者失效的client不得幹預快速的client的請求,使得每個client都能有效的等待。
原子性:更新只能成功或者失敗,沒有中間狀態。
順序性:包括全局有序和偏序兩種:全局有序是指如果在一臺服務器上消息a在消息b前發布,則在所有Server上消息a都將在消息b前被發布;偏序是指如果一個消息b在消息a後被同一個發送者發布,a必將排在b前面。

Zookeeper工作原理
1、在zookeeper的集群中,各個節點共有下面3種角色和4種狀態:

角色:leader,follower,observer
狀態:leading,following,observing,looking

Zookeeper的核心是原子廣播,這個機制保證了各個Server之間的同步。實現這個機制的協議叫做Zab協議(ZooKeeper Atomic Broadcast protocol)。Zab協議有兩種模式,它們分別是恢復模式(Recovery選主)和廣播模式(Broadcast同步)。當服務啟動或者在領導者崩潰後,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和leader的狀態同步以後,恢復模式就結束了。狀態同步保證了leader和Server具有相同的系統狀態。

為了保證事務的順序一致性,zookeeper采用了遞增的事務id號(zxid)來標識事務。所有的提議(proposal)都在被提出的時候加上了zxid。實現中zxid是一個64位的數字,它高32位是epoch用來標識leader關系是否改變,每次一個leader被選出來,它都會有一個新的epoch,標識當前屬於那個leader的統治時期。低32位用於遞增計數。

每個Server在工作過程中有4種狀態:

LOOKING:當前Server不知道leader是誰,正在搜尋。

LEADING:當前Server即為選舉出來的leader。

FOLLOWING:leader已經選舉出來,當前Server與之同步。

OBSERVING:observer的行為在大多數情況下與follower完全一致,但是他們不參加選舉和投票,而僅僅接受(observing)選舉和投票的結果。

Zookeeper集群節點
Zookeeper節點部署越多,服務的可靠性越高,建議部署奇數個節點,因為zookeeper集群是以宕機個數過半才會讓整個集群宕機的。
需要給每個zookeeper 1G左右的內存,如果可能的話,最好有獨立的磁盤,因為獨立磁盤可以確保zookeeper是高性能的。如果你的集群負載很重,不要把zookeeper和RegionServer運行在同一臺機器上面,就像DataNodes和TaskTrackers一樣。

實驗環境:

主機名 系統 IP

linux-node1 CentOS Linux release 7.5 192.168.10.10

linux-node2 CentOS Linux release 7.5 192.168.10.20

linux-node3 CentOS Linux release 7.5 192.168.10.20

二、Zookeeper安裝
Zookeeper運行需要java環境,需要安裝 jdk,註:每臺服務器上面都需要安裝zookeeper、jdk,建議本地下載好需要的安裝包然後上傳到服務器上面,服務器上面下載速度太慢。

2.1 三臺服務器安裝 JDK
[root@linux-node1 tools]# tar -zxvf jdk-8u181-linux-x64.tar.gz -C /usr/local/

[root@linux-node1 tools]# cd /usr/local/
[root@linux-node1 local]# ll
總用量 0
drwxr-xr-x. 2 root root 6 4月 11 12:59 bin
drwxr-xr-x. 2 root root 6 4月 11 12:59 etc
drwxr-xr-x. 2 root root 6 4月 11 12:59 games
drwxr-xr-x. 2 root root 6 4月 11 12:59 include
drwxr-xr-x. 7 10 143 245 7月 7 2018 jdk1.8.0_181
drwxr-xr-x. 2 root root 6 4月 11 12:59 lib
drwxr-xr-x. 2 root root 6 4月 11 12:59 lib64
drwxr-xr-x. 2 root root 6 4月 11 12:59 libexec
drwxr-xr-x. 2 root root 6 4月 11 12:59 sbin
drwxr-xr-x. 5 root root 49 6月 25 2018 share
drwxr-xr-x. 2 root root 6 4月 11 12:59 src
[root@linux-node1 local]# mv jdk1.8.0_181 jdk

配置環境變量,增加以下內容:
[root@linux-node1 ~]# vim /etc/profile
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
[root@linux-node1 ~]# source /etc/profile

[root@linux-node1 local]# java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

2.2、Zookeeper安裝
Zookeeper鏈接:http://zookeeper.apache.org/

[root@linux-node1 tools]# wget https://mirrors.cnnic.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz --no-check-certificate

[root@linux-node1 tools]# tar -zxvf zookeeper-3.4.13.tar.gz -C /usr/local/
[root@linux-node1 tools]# cd /usr/local && mv zookeeper-3.4.13 zookeeper

[root@linux-node1 local]# cp zookeeper/conf/zoo_sample.cfg zookeeper/conf/zoo.cfg

#把zookeeper加入到環境變量。
[root@linux-node1 local]# echo -e "# append zk_env\nexport PATH=$PATH:/usr/local//zookeeper/bin" >> /etc/profile

[root@linux-node1 local]# source /etc/profile

三、Zookeeper集群配置
註意:搭建zookeeper集群時,一定要先停止已經啟動的zookeeper節點。

3.1、Zookeeper配置文件修改

[root@linux-node1 local]# egrep -v "^#|^$" zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataLogDir=/usr/local/zookeeper/logs
dataDir=/usr/local/zookeeper/data
clientPort=2181
autopurge.snapRetainCount=500
autopurge.purgeInterval=24
server.1= 192.168.10.10:2888:3888
server.2= 192.168.10.20:2888:3888
server.3= 192.168.10.30:2888:3888

#創建相關目錄,三臺節點都需要

[root@linux-node1 local]# mkdir -p /usr/local/zookeeper/{logs,data}

#其余zookeeper節點安裝完成之後,同步配置文件zoo.cfg。

3.2、配置參數說明
tickTime這個時間是作為zookeeper服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是說每個tickTime時間就會發送一個心跳。

initLimit這個配置項是用來配置zookeeper接受客戶端(這裏所說的客戶端不是用戶連接zookeeper服務器的客戶端,而是zookeeper服務器集群中連接到leader的follower 服務器)初始化連接時最長能忍受多少個心跳時間間隔數。

當已經超過10個心跳的時間(也就是tickTime)長度後 zookeeper 服務器還沒有收到客戶端的返回信息,那麽表明這個客戶端連接失敗。總的時間長度就是 10*2000=20秒。

syncLimit這個配置項標識leader與follower之間發送消息,請求和應答時間長度,最長不能超過多少個tickTime的時間長度,總的時間長度就是5*2000=10秒。

dataDir顧名思義就是zookeeper保存數據的目錄,默認情況下zookeeper將寫數據的日誌文件也保存在這個目錄裏;

clientPort這個端口就是客戶端連接Zookeeper服務器的端口,Zookeeper會監聽這個端口接受客戶端的訪問請求;

server.A=B:C:D中的A是一個數字,表示這個是第幾號服務器,B是這個服務器的IP地址,C第一個端口用來集群成員的信息交換,表示這個服務器與集群中的leader服務器交換信息的端口,D是在leader掛掉時專門用來進行選舉leader所用的端口。

3.3、創建ServerID標識
除了修改zoo.cfg配置文件外,zookeeper集群模式下還要配置一個myid文件,這個文件需要放在dataDir目錄下。

這個文件裏面有一個數據就是A的值(該A就是zoo.cfg文件中server.A=B:C:D中的A),在zoo.cfg文件中配置的dataDir路徑中創建myid文件。

#在192.168.10.10 服務器上面創建myid文件,並設置值為1,同時與zoo.cfg文件裏面的server.1保持一致,如下:
[root@linux-node1 local]# echo "1" >/usr/local/zookeeper/data/myid

[root@linux-node1 local]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.10 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::1073:2cbf:aa21:920b prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:d3:c6:80 txqueuelen 1000 (Ethernet)
RX packets 188131 bytes 267811277 (255.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 51922 bytes 5316450 (5.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 283 bytes 24936 (24.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 283 bytes 24936 (24.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

#在192.168.10.20 服務器上面創建myid文件,並設置值為2,同時與zoo.cfg文件裏面的server.1保持一致,如下:

[root@linux-node2 local]# echo "2" >/usr/local/zookeeper/data/myid
[root@linux-node2 local]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.20 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::e690:3c3c:62ba:c9e2 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b5:43:96 txqueuelen 1000 (Ethernet)
RX packets 187362 bytes 267661578 (255.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 53707 bytes 5386328 (5.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 216 bytes 19064 (18.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 216 bytes 19064 (18.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

#在192.168.10.30 服務器上面創建myid文件,並設置值為3,同時與zoo.cfg文件裏面的server.1保持一致,如下:

[root@linux-node3 local]# echo "3" >/usr/local/zookeeper/data/myid
[root@linux-node3 local]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.30 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::a3a:d1af:e5cb:3c86 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:42:e2:7f txqueuelen 1000 (Ethernet)
RX packets 187924 bytes 267761239 (255.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 53236 bytes 5392570 (5.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 242 bytes 21496 (20.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 242 bytes 21496 (20.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

到此,相關配置完成。

四、Zookeeper 集群查看

#在 linux-node1、linux-node2、linux-node3 啟動服務。

[root@linux-node1 local]# /usr/local/zookeeper/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

[root@linux-node2 local]# /usr/local/zookeeper/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

[root@linux-node3 local]# /usr/local/zookeeper/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

2、啟動完成之後查看每個節點的狀態
#linux-node1
[root@linux-node1 conf]# /usr/local/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: follower

[root@linux-node1 conf]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.10 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::1073:2cbf:aa21:920b prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:d3:c6:80 txqueuelen 1000 (Ethernet)
RX packets 189426 bytes 267929552 (255.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 52879 bytes 5437430 (5.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 305 bytes 26388 (25.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 305 bytes 26388 (25.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

#linux-node2
[root@linux-node2 conf]# /usr/local/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: leader

[root@linux-node2 conf]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.20 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::e690:3c3c:62ba:c9e2 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b5:43:96 txqueuelen 1000 (Ethernet)
RX packets 188555 bytes 267768644 (255.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 55247 bytes 5534675 (5.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 230 bytes 20062 (19.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 230 bytes 20062 (19.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

linux-node3
[root@linux-node3 conf]# /usr/local/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: follower
[root@linux-node3 conf]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.30 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::a3a:d1af:e5cb:3c86 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:42:e2:7f txqueuelen 1000 (Ethernet)
RX packets 189101 bytes 267862278 (255.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 54037 bytes 5488590 (5.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 252 bytes 22258 (21.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 252 bytes 22258 (21.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

#從上面可以看出,linux-node1,linux-node3兩臺服務器zookeeper的狀態是follow模式,linux-node2這臺服務器zookeeper的狀態是leader模式。

五、Zookeeper集群連接
Zookeeper集群搭建完畢之後,可以通過客戶端腳本連接到zookeeper集群上面,對客戶端來說,zookeeper集群是一個整體,連接到zookeeper集群實際上感覺在獨享整個集群的服務。

[root@linux-node1 bin]# /usr/local/zookeeper/bin/zkCli.sh -server 192.168.10.20:2181
Connecting to 192.168.10.20:2181
2018-06-25 18:44:57,700 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.13-2d71af4dbe22557fda74f9a9b4309b15a7487f03, built on 06/29/2018 04:05 GMT
2018-06-25 18:44:57,704 [myid:] - INFO [main:Environment@100] - Client environment:host.name=linux-node1
2018-06-25 18:44:57,704 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.8.0_181
2018-06-25 18:44:57,706 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
2018-06-25 18:44:57,707 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/usr/local/jdk/jre
2018-06-25 18:44:57,707 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=/usr/local/zookeeper/bin/../build/classes:/usr/local/zookeeper/bin/../build/lib/.jar:/usr/local/zookeeper/bin/../lib/slf4j-log4j12-1.7.25.jar:/usr/local/zookeeper/bin/../lib/slf4j-api-1.7.25.jar:/usr/local/zookeeper/bin/../lib/netty-3.10.6.Final.jar:/usr/local/zookeeper/bin/../lib/log4j-1.2.17.jar:/usr/local/zookeeper/bin/../lib/jline-0.9.94.jar:/usr/local/zookeeper/bin/../lib/audience-annotations-0.5.0.jar:/usr/local/zookeeper/bin/../zookeeper-3.4.13.jar:/usr/local/zookeeper/bin/../src/java/lib/.jar:/usr/local/zookeeper/bin/../conf:.:/usr/local/jdk/lib/dt.jar:/usr/local/jdk/lib/tools.jar
2018-06-25 18:44:57,707 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2018-06-25 18:44:57,707 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=/tmp
2018-06-25 18:44:57,707 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=<NA>
2018-06-25 18:44:57,707 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Linux
2018-06-25 18:44:57,707 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=amd64
2018-06-25 18:44:57,707 [myid:] - INFO [main:Environment@100] - Client environment:os.version=3.10.0-862.el7.x86_64
2018-06-25 18:44:57,707 [myid:] - INFO [main:Environment@100] - Client environment:user.name=root
2018-06-25 18:44:57,707 [myid:] - INFO [main:Environment@100] - Client environment:user.home=/root
2018-06-25 18:44:57,708 [myid:] - INFO [main:Environment@100] - Client environment:user.dir=/usr/local/zookeeper/bin
2018-06-25 18:44:57,709 [myid:] - INFO [main:ZooKeeper@442] - Initiating client connection, connectString=192.168.10.20:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@4b9af9a9
Welcome to ZooKeeper!
JLine support is enabled
2018-06-25 18:44:57,801 [myid:] - INFO [main-SendThread(192.168.10.20:2181):ClientCnxn$SendThread@1029] - Opening socket connection to server 192.168.10.20/192.168.10.20:2181. Will not attempt to authenticate using SASL (unknown error)
2018-06-25 18:44:57,876 [myid:] - INFO [main-SendThread(192.168.10.20:2181):ClientCnxn$SendThread@879] - Socket connection established to 192.168.10.20/192.168.10.20:2181, initiating session
[zk: 192.168.10.20:2181(CONNECTING) 0] 2018-06-25 18:44:57,936 [myid:] - INFO [main-SendThread(192.168.10.20:2181):ClientCnxn$SendThread@1303] - Session establishment complete on server 192.168.10.20/192.168.10.20:2181, sessionid = 0x20000a259f20001, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null

配置 Zookeeper 集群