zookeeper是一個分佈式協調服務:html
Zookeeper是一個高效的分佈式協調服務,能夠提供配置信息管理、命名、分佈式同步、集羣管理、數據庫切換等服務。它不適合用來存儲大量信息,能夠用來存儲一些配置、發佈與訂閱等少許信息。Hadoop、Storm、消息中間件、RPC服務框架、分佈式數據庫同步系統,這些都是Zookeeper的應用場景。node
二、zookeeper集羣機制linux
Zookeeper集羣中節點個數通常爲奇數個(>=3),若集羣中Master掛掉,剩餘節點個數在半數以上時,就能夠推舉新的主節點,繼續對外提供服務 數據庫
三、zookeeper特性apache
- Zookeeper:一個leader,多個follower組成的集羣
- 全局數據一致:每一個server保存一份相同的數據副本,client不管鏈接到哪一個server,數據都是一致的
- 分佈式讀寫,更新請求轉發,由leader實施
- 更新請求順序進行,來自同一個client的更新請求按其發送順序依次執行
- 數據更新原子性,一次數據更新要麼成功,要麼失敗
- 實時性,在必定時間範圍內,client能讀到最新數據
四、zookeeper數據結構服務器
Zookeeper使用的數據結構爲樹形結構,根節點爲"/"。Zookeeper集羣中的節點,根據其身份特性分爲leader、follower、observer。leader負責客戶端writer類型的請求;follower負責客戶端reader類型的請求,並參與leader選舉;observer是特殊的follower,能夠接收客戶端reader請求,可是不會參與選舉,能夠用來擴容系統支撐能力,提升讀取速度。數據結構
五、zookeeper原理及內部選舉機制框架
原理:zookeeper在配置文件中並無指定master和slave,可是,zookeeper在工做時,只有一個節點爲leader,其他節點爲follower,leader是經過內部的選舉機制臨時產生的。分佈式
選舉機制:(兩種狀況)oop
(1)全新集羣paxos
假設有五臺服務器組成的zookeeper集羣,它們的id從1-5,同時它們都是最新啓動的,也就是沒有歷史數據,在存放數據量這一點上,都是同樣的.假設這些服務器依序啓動,來看看會發生什麼.
1) 服務器1啓動,此時只有它一臺服務器啓動了,它發出去的報沒有任何響應,因此它的選舉狀態一直是LOOKING狀態
2) 服務器2啓動,它與最開始啓動的服務器1進行通訊,互相交換本身的選舉結果,因爲二者都沒有歷史數據,因此id值較大的服務器2勝出,可是因爲沒有達到超過半數以上的服務器都贊成選舉它(這個例子中的半數以上是3),因此服務器1,2仍是繼續保持LOOKING狀態.
3) 服務器3啓動,根據前面的理論分析,服務器3成爲服務器1,2,3中的老大,而與上面不一樣的是,此時有三臺服務器選舉了它,因此它成爲了此次選舉的leader.
4) 服務器4啓動,根據前面的分析,理論上服務器4應該是服務器1,2,3,4中最大的,可是因爲前面已經有半數以上的服務器選舉了服務器3,因此它只能接收當小弟的命了.
5) 服務器5啓動,同4同樣,當小弟.
(2)非全新集羣(數據恢復)
初始化的時候,是按照上述的說明進行選舉的,可是當zookeeper運行了一段時間以後,有機器down掉,從新選舉時,選舉過程就相對複雜了。
須要加入數據id、leader id和邏輯時鐘。
數據id:數據新的id就大,數據每次更新都會更新id。
Leader id:就是咱們配置的myid中的值,每一個機器一個。
邏輯時鐘:這個值從0開始遞增,每次選舉對應一個值,也就是說: 若是在同一次選舉中,那麼這個值應該是一致的 ; 邏輯時鐘值越大,說明這一次選舉leader的進程更新.
選舉的標準就變成:
一、邏輯時鐘小的選舉結果被忽略,從新投票
二、統一邏輯時鐘後,數據id大的勝出
三、數據id相同的狀況下,leader id大的勝出
根據這個規則選出leader。
六、zookeeper集羣的搭建
- 準備三臺機器:hadoop1(192.168.1.11)、hadoop2(192.168.1.12)、hadoop3(192.168.1.13),而且安裝jdk(可參照筆記:http://www.javashuo.com/article/p-rtvzuadn-eq.html)。
- 將zookeeper安裝包上傳到hadoop1的/usr/local中:wget http://apache.fayea.com/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz 。
- 解壓:tar -zxvf /usr/local/zookeeper-3.4.5.tar.gz
重命名:mv zookeeper-3.4.5.tar.gz zookeeper
- 修改環境變量
vi /etc/profile
添加內容:export ZOOKEEPER_HOME=/usr/local/zookeeper
export PATH=.:$ZOOKEEPER_HOME/bin....
刷新環境變量
source /etc/profile
注意:3臺機器都要修改
- 修改配置文件
cd /usr/local/zookeeper/conf
cp zoo_sample.cfg zoo.cfg
vi zoo.cfg
添加內容:
maxClientCnxns=60
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper/data
dataLogDir=/data/logs/zookeeper
clientPort=2181 (客戶端鏈接端口)
server.1=192.168.1.11:2888:3888 (主機名, 心跳端口、數據端口)
server.2=192.168.1.12:2888:3888 (都是默認端口)
server.3=192.168.1.13:2888:3888 (2888表示zookeeper程序監聽端口,3888表示zookeeper選舉通訊端口)
建立文件夾
mkdir /usr/local/zookeeper/data
mkdir /usr/local/zookeeper/log
在data文件夾中新建myid文件,myid文件的內容爲1(一句話建立:echo 1 > myid)
cd data
vi myid
添加內容:1
- 把zookeeper目錄複製到hadoop2和hadoop3中
設置三個機器的本機免密登陸(三臺機器配置同樣):
scp -r /usr/local/zookeeper/ hadoop2:/usr/local/
scp -r /usr/local/zookeeper/ hadoop3:/usr/local/
將hadoop0中的環境變量複製到hadoop2和hadoop3中
scp /etc/profile hadoop2:/etc/
scp /etc/profile hadoop3:/etc/
環境變量複製好了之後,在hadoop2和hadoop3上都要執行source /etc/profile
- 把hadoop2中相應的myid的值改成2
vi /usr/local/zk/data/myid 將裏面的值改成2
把hadoop3中相應的myid的值改成3
vi /usr/local/zk/data/myid 將裏面的值改成3
- 將三臺機器的防火牆關閉掉,service iptables stop ,查看service iptables status,還有selinux。
啓動,在三個節點上分別都要執行命令zkServer.sh start
cd /usr/local/zk/bin
ls
zkServer.sh start
啓動完了以後,在bin目錄下多了一個zookeeper.out
- 檢驗,jps查看進程,會出現進程QuorumPeerMain
在三個節點上依次執行命令zkServer.sh status(能夠看到MODE,誰是leader,誰是follower)
hadoop1:follower
hadoop2:leader
hadoop3:follower
七、zookeeper命令行客戶端
執行zkCli.sh,客戶端鏈接上服務器hadoop1。
ls / 查找根目錄
create /test abc 建立節點並賦值
get /test 獲取指定節點的值
set /test cb 設置已存在節點的值
rmr /test 遞歸刪除節點
delete /test/test01 刪除不存在子節點的節點
使用 ls 命令來查看當前 ZooKeeper 中所包含的內容:
建立一個新的 znode ,使用 create /zk 「myData」 。這個命令建立了一個新的 znode 節點「 zk 」以及與它關聯的字符串:
咱們運行 get 命令來確認 znode 是否包含咱們所建立的字符串:
#監聽這個節點hadoop2的變化,當另一個客戶端localhost改變/zk時(見4),它會打出下面的
#WATCHER::
#WatchedEvent state:SyncConnected type:NodeDataChanged path:/zk
[zk: localhost:2181(CONNECTED) 4] get /zk watch
下面咱們經過 set 命令來對 zk 所關聯的字符串進行設置:
下面咱們將剛纔建立的 znode 刪除:
刪除節點:rmr