:zookeeper是為其它分布式程序提供:主從協(xié)調(diào)闰挡、服務(wù)器節(jié)點(diǎn)動(dòng)態(tài)上下線涕蜂、統(tǒng)一配置管理、分布式共享鎖皿哨、統(tǒng)一名稱 等服務(wù)的浅侨。同時(shí)zookeeper本身也是分布式程序的,只要半數(shù)以上節(jié)點(diǎn)存活证膨,zookeeper就能正常服務(wù)如输。所以建議zookeeper搭建在奇數(shù)的機(jī)器上。
zookeeper特性
- Zookeeper集群由一個(gè)leader央勒,多個(gè)follower組成不见。
- 全局?jǐn)?shù)據(jù)一致:每個(gè)server保存一份相同的數(shù)據(jù)副本,client無論連接到哪個(gè)server崔步,數(shù)據(jù)都是一致的
- 分布式讀寫稳吮,更新請(qǐng)求轉(zhuǎn)發(fā),由leader實(shí)施
- 更新請(qǐng)求順序進(jìn)行井濒,來自同一個(gè)client的更新請(qǐng)求按其發(fā)送順序依次執(zhí)行
- 數(shù)據(jù)更新原子性灶似,一次數(shù)據(jù)更新要么成功,要么失敗
- 實(shí)時(shí)性瑞你,在一定時(shí)間范圍內(nèi)喻奥,client能讀到最新數(shù)據(jù)
zookeeper原理及內(nèi)部選舉機(jī)制
在配置文件中zookeeper并沒有指定master和slave,zookeeper啟動(dòng)后會(huì)通過內(nèi)部的選舉機(jī)制臨時(shí)產(chǎn)生的捏悬。在一個(gè)zookeeper集群中,會(huì)選舉出一個(gè)節(jié)點(diǎn)為leader润梯,其余節(jié)點(diǎn)為follower过牙。下面說下選舉機(jī)制的兩種情況:
1. 新啟動(dòng)的zookeeper集群(從未選舉成功過)
新配置的zookeeper集群依次,它們都是最新啟動(dòng)的纺铭,也就是沒有歷史數(shù)據(jù)寇钉,在存放數(shù)據(jù)量這一點(diǎn)上都是一樣的。一般這種情況下舶赔,ID大的的會(huì)被選舉為L(zhǎng)eader扫倡。
2. 非全新集群(數(shù)據(jù)恢復(fù))
初始化的時(shí)候,是按照上述的說明進(jìn)行選舉的,但是當(dāng)zookeeper運(yùn)行了一段時(shí)間之后撵溃,有機(jī)器down掉疚鲤,重新選舉時(shí),選舉過程就相對(duì)復(fù)雜了缘挑。需要加入數(shù)據(jù)id集歇、leader id和邏輯時(shí)鐘。
- 數(shù)據(jù)id:數(shù)據(jù)新的id就大语淘,數(shù)據(jù)每次更新都會(huì)更新id诲宇。
- Leader id:就是我們配置的myid中的值,每個(gè)機(jī)器一個(gè)惶翻。
- 邏輯時(shí)鐘:這個(gè)值從0開始遞增,每次選舉對(duì)應(yīng)一個(gè)值,也就是說: 如果在同一次選舉中,那么這個(gè)值應(yīng)該是一致的 ; 邏輯時(shí)鐘值越大,說明這一次選舉leader的進(jìn)程更新.
選舉的標(biāo)準(zhǔn)就變成:
- 邏輯時(shí)鐘小的選舉結(jié)果被忽略姑蓝,重新投票
- 統(tǒng)一邏輯時(shí)鐘后,數(shù)據(jù)id大的勝出
- 數(shù)據(jù)id相同的情況下吕粗,leader id大的勝出
根據(jù)這個(gè)規(guī)則選出leader纺荧。
搭建三臺(tái)zookeeper集群
先準(zhǔn)備好三臺(tái)CentOS 7服務(wù)器,服務(wù)器安裝Java1.8 +環(huán)境溯泣。
1. 安裝Java 1.8
略虐秋。
2. 安裝zookeeper
截止寫這篇文檔,zookeeper的穩(wěn)定版 最新版本為:zookeeper-3.4.13垃沦。以下操作三臺(tái)機(jī)器相同客给,不同處有標(biāo)注。
# wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz
# tar -zxvf zookeeper-3.4.13.tar.gz -C /opt/
# ln -s /opt/zookeeper-3.4.13/ /opt/zookeeper
# vim /etc/profile.d/zookeeper.sh
export ZK_HOME=/opt/zookeeper
export PATH=$PATH:$ZK_HOME/bin
# source /etc/profile.d/zookeeper.sh
# rm /opt/zookeeper/bin/*.cmd
# cp /opt/zookeeper/conf/zoo_sample.cfg /opt/zookeeper/conf/zoo.cfg
# vim /opt/zookeeper/conf/zoo.cfg
dataDir=/opt/zookeeper/data
dataLogDir=/opt/zookeeper/logs
server.1=172.16.5.137:2888:3888
server.2=172.16.5.138:2888:3888
server.3=172.16.5.139:2888:3888
# mkdir -p /opt/zookeeper/{logs,data}
每臺(tái)Server ID寫入文件肢簿,三臺(tái)不相同
# echo 3 > /opt/zookeeper/data/myid
# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Mode: follower
配置文件說明:
- tickTime:這個(gè)時(shí)間是作為zookeeper服務(wù)器之間或客戶端與服務(wù)器之間維持心跳的時(shí)間間隔,也就是說每個(gè)tickTime時(shí)間就會(huì)發(fā)送一個(gè)心跳靶剑。
- initLimit:這個(gè)配置項(xiàng)是用來配置zookeeper接受客戶端(這里所說的客戶端不是用戶連接zookeeper服務(wù)器的客戶端,而是zookeeper服務(wù)器集群中連接到leader的follower 服務(wù)器)初始化連接時(shí)最長(zhǎng)能忍受多少個(gè)心跳時(shí)間間隔數(shù)。當(dāng)已經(jīng)超過10個(gè)心跳的時(shí)間(也就是tickTime)長(zhǎng)度后 zookeeper 服務(wù)器還沒有收到客戶端的返回信息,那么表明這個(gè)客戶端連接失敗池充∽總的時(shí)間長(zhǎng)度就是 10*2000=20秒。
- syncLimit:這個(gè)配置項(xiàng)標(biāo)識(shí)leader與follower之間發(fā)送消息,請(qǐng)求和應(yīng)答時(shí)間長(zhǎng)度,最長(zhǎng)不能超過多少個(gè)tickTime的時(shí)間長(zhǎng)度,總的時(shí)間長(zhǎng)度就是5*2000=10秒收夸。
- dataDir:顧名思義就是zookeeper保存數(shù)據(jù)的目錄,默認(rèn)情況下zookeeper將寫數(shù)據(jù)的日志文件也保存在這個(gè)目錄里坑匠;
- clientPort:這個(gè)端口就是客戶端連接Zookeeper服務(wù)器的端口,Zookeeper會(huì)監(jiān)聽這個(gè)端口接受客戶端的訪問請(qǐng)求;
- server.A=B:C:D:中的A是一個(gè)數(shù)字,表示這個(gè)是第幾號(hào)服務(wù)器,B是這個(gè)服務(wù)器的IP地址卧惜,C第一個(gè)端口用來集群成員的信息交換,表示這個(gè)服務(wù)器與集群中的leader服務(wù)器交換信息的端口厘灼,D是在leader掛掉時(shí)專門用來進(jìn)行選舉leader所用的端口。