0,Zookeeper基本原理
ZooKeeper集群由一組Server節點組成,這一組Server節點中存在一個角色為Leader的節點,其他節點都為Follower。當客戶端Client連接到ZooKeeper集群,並且執行寫請求時,這些請求會被發送到Leader節點上,然后Leader節點上數據變更會同步到集群中其他的Follower節點。
ZooKeeper采用一種稱為Leader election的選舉算法(也有稱做:分布式選舉算法-Paxos)的。在整個集群運行過程中,只有一個Leader,其他的都是Follower,如果ZooKeeper集群在運行過程中Leader出了問題,系統會采用該算法重新選出一個Leader,
ZooKeeper用於三台以上的服務器集群之中,只要還有超過半數的服務器在線,ZooKeeper就能夠正常提供服務,過半,意味着實際能夠有效參與選舉的節點數量是奇書個數,否者不能有效的過半
Zookeeper邏輯圖如下,
- 客戶端可以連接到每個server,每個server的數據完全相同。
- 每個follower都和leader有連接,接受leader的數據更新操作。
- Server記錄事務日志和快照到持久存儲。
- 大多數server可用,整體服務就可用。
- Leader節點在接收到數據變更請求后,首先將變更寫入本地磁盤,以作恢復之用。當所有的寫請求持久化到磁盤以后,才會將變更應用到內存中。
- ZooKeeper使用了一種自定義的原子消息協議,在消息層的這種原子特性,保證了整個協調系統中的節點數據或狀態的一致性。Follower基於這種消息協議能夠保證本地的ZooKeeper數據與Leader節點同步,然后基於本地的存儲來獨立地對外提供服務。
- 當一個Leader節點發生故障失效時,失敗故障是快速響應的,消息層負責重新選擇一個Leader,繼續作為協調服務集群的中心,處理客戶端寫請求,並將ZooKeeper協調系統的數據變更同步(廣播)到其他的Follower節點。
1,系統環境配置
我這里使用的是在VMWare中安裝centos7每個虛擬機都選擇橋接模式。即可在網絡中獨立分配一個IP,每台機器單獨設定一個IP。
- 配置hosts:vi /etc/hosts
192.168.137.122 master 192.168.137.123 slave1 192.168.137.124 slave2
- 關閉防火牆 (很重要,不然會出現No rout to host異常)
systemctl status firewalld.service #檢查防火牆狀態 systemctl stop firewalld.service #關閉防火牆 systemctl disable firewalld.service #禁止開機啟動防火牆
- 關閉SELINUX:vi /etc/selinux/config
#SELINUX=enforcing #注釋掉 #SELINUXTYPE=targeted #注釋掉 SELINUX=disabled #增加
- 4. 立即生效配置
setenforce 0 #使配置立即生效
2,java安裝環境變量配置
略
3,配置無密鑰的SSH訪問
在此處為了方便,我將所有網內的節點機器都互相能SSH無密鑰登錄,可以理解為雙向無密鑰登錄。
- 使用下列命令在每個虛擬機上都生成密鑰
ssh-keygen -t rsa #生成密鑰,一路回車即可,只適用於測試環境,正式環境請設定密碼
- 每個節點機器的公鑰傳輸到master機器上
scp ~/.ssh/id_rsa.pub master:~/.ssh/slave1.id_rsa.pub #在slave1中,將公鑰文件傳輸至master機器上,並修改文件名為slave1.id_rsa.pub scp ~/.ssh/id_rsa.pub master:~/.ssh/slave2.id_rsa.pub #在slave2中,將公鑰文件傳輸至master機器上,並修改文件名為slave2.id_rsa.pub
- 在master機器上生成統一的authorized_keys
cd ~/.ssh cat id_rsa.pub >> authorized_keys #這個是master生成的公鑰,就在本機 cat slave1.id_rsa.pub >> authorized_keys cat slave2.id_rsa.pub >> authorized_keys
完成后可以使用rm -f slave1.id_rsa.pub刪除拷貝過來的秘鑰文件
- 將統一的authorized_keys分發至每個節點
scp authorized_keys root@master1:~/.ssh scp authorized_keys root@master2:~/.ssh
authorized_keys是公鑰的字典文件,這樣下來所有的,所有節點的authorized_keys文件中記錄的秘鑰都相同了,因為可以實現每個機器的ssh互通了。
4,Zookeeper集群安裝
zookeeper安裝非常簡單,只要獲取到 Zookeeper 的壓縮包並解壓到某個目錄,修改一下配置即可。
- 下載zookeeper-3.4.8,使用下列命令解壓到指定路徑
tar -zxvf zookeeper-3.4.8.tar.gz
mv zookeeper-3.4.8 /home/zookeeper #這里可以指定你喜歡的任意目錄 - 修改環境變量:vi /etc/profile 加入下列內容
# set zookeeperpath export ZOOKEEPER_HOME=/home/zookeeper export PATH=$PATH:$ZOOKEEPER_HOME/bin
- 使用下面命令復制配置文件(也可直接建立)
cp /home/zookeeper/conf/zoo_sample.cfg /home/zookeeper/conf/zoo.cfg
- 使用 vi /home/zookeeper/conf/zoo.cfg 修改配置文件,具體內容如下:
# The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=/home/zookeeper/zkdata dataLogDir=/home/zookeeper/zklog # the port at which the clients will connect clientPort=2181 # the maximum number of client connections. # increase this if you need to handle more clients #maxClientCnxns=60 # # Be sure to read the maintenance section of the # administrator guide before turning on autopurge. # # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance # # The number of snapshots to retain in dataDir #autopurge.snapRetainCount=3 # Purge task interval in hours # Set to "0" to disable auto purge feature #autopurge.purgeInterval=1 server.1=master:2888:3888 server.2=slaver1:2888:3888 server.3=slaver2:2888:3888
tickTime: zookeeper中使用的基本時間單位, 毫秒值.
dataDir: 數據目錄. 可以是任意目錄.
dataLogDir: log目錄, 同樣可以是任意目錄. 如果沒有設置該參數, 將使用和dataDir相同的設置.
clientPort: 監聽client連接的端口號.
nitLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這里所說的客戶端不是用戶連接 Zookeeper 服務器的客戶端,而是 Zookeeper 服務器集群中連接到 Leader 的 Follower 服務器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過 5個心跳的時間(也就是 tickTime)長度后 Zookeeper 服務器還沒有收到客戶端的返回信息,那么表明這個客戶端連接失敗。總的時間長度就是 5*2000=10 秒
syncLimit:這個配置項標識 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 2*2000=4 秒
server.A=B:C:D:其中 A 是一個數字,表示這個是第幾號服務器;B 是這個服務器的 ip 地址;C 表示的是這個服務器與集群中的 Leader 服務器交換信息的端口;D 表示的是萬一集群中的 Leader 服務器掛了,需要一個端口來重新進行選舉,選出一個新的 Leader,而這個端口就是用來執行選舉時服務器相互通信的端口。如果是偽集群的配置方式,由於 B 都是一樣,所以不同的 Zookeeper 實例通信端口號不能一樣,所以要給它們分配不同的端口號。 - 創建myid文件:在zoo.cfg指定的dataDir目錄下建立以服務器節點對應的myid文件,如master節點中,創建myid文件內容為1,slave1中創建myid文件內容為2...
- 使用下列命令將zoopeeper拷貝到其他節點
scp /home/zookeeper root@master1: /home/ scp /home/zookeeper root@master2: /home/
完成后,只需在其他節點上修改vi /etc/profile,以及對應的myid,即可
4,啟動Zookeeper集群
- 在所有節點執行下列命令啟動
cd /home/zookeeper bin/zkServer.sh start
正常會顯示如下狀態
- 使用jps命令查看系統進程
- 使用下列命令檢查運行狀態
bin/zkServer.sh -status
如顯示一下狀態表示啟動失敗
具體失敗原因可閱讀zookeeper/zookeeper.out文件查閱 如顯示一下狀態表示啟動成功
查看其余節點,整個包括集群中各個結點的角色會有一個leader,其他都是follower。
我們通過more zookeeper.out檢查啟動輸入日志,會發現有下列異常
我啟動的順序是master>slave1>slave2,由於ZooKeeper集群啟動的時候,每個結點都試圖去連接集群中的其它結點,先啟動的肯定連不上后面還沒啟動的,所以上面日志前面部分的異常是可以忽略的。通過后面部分可以看到,集群在選出一個Leader后,最后穩定了。 其他結點可能也出現類似問題,屬於正常。 - 客戶端連接測試: 對於客戶端來說,ZooKeeper是一個整體(ensemble),無論連接到那個節點,實際上都在獨享整個ZooKeeper集群的服務,所以,我們可以在任何一個結點上建立到服務集群的連接
5,參考
- zookeeper項目使用幾點小結 http://agapple.iteye.com/blog/1184023
- ZooKeeper架構設計及其應用要點 http://shiyanjun.cn/archives/474.html
- ZooKeeper原理及使用 http://blog.csdn.net/xinguan1267/article/details/38422149
- Zookeeper 的學習與運用 http://blog.jiguang.cn/push_zookeeper_study_usage/
- Zookeeper-Zookeeper leader選舉 http://www.cnblogs.com/yuyijq/p/4116365.html
- zookeeper原理 http://cailin.iteye.com/blog/2014486