ZooKeeper是一個分佈式的,開放源碼的分佈式應用程序協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個爲分佈式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分佈式同步、組服務等。
ZooKeeper的基本運轉流程:
1、選舉Leader。
2、同步數據。
3、選舉Leader過程中算法有很多,但要達到的選舉標準是一致的。
4、Leader要具有最高的執行ID,類似root權限。
5、集羣中大多數的機器得到響應並follow選出的Leader。
目前阿里開源的dubbo分佈式服務框架推薦的註冊中心。其更詳細原理可以參考:http://cailin.iteye.com/blog/20144
安裝
接下來我們進入zookeeper的安裝環節,zookeeper的安裝總的來說比較簡單,這裏我準備了3臺linux虛擬機,模擬集羣環境,有條件的同學可以自己裝3臺(最少),其實集羣和單機的區別不是太大,但是集羣時節點數量一定是奇數(2n+1如3,5,7)。
工具: CentOS.7,zookeeper-3.4.6,Xshell5
注:zookeeper本身由java編寫,運行在java環境,故同學們必須先裝好java環境,纔可以繼續zookeeper的安裝,這裏我對java環境不做講解
如有安裝java的需要請看我http://blog.csdn.net/qq_15760109/article/details/79228842
服務器CentOS7_64_1的ip:192.168.2.101,hostname:h1
單機模式
安裝包下載
首先使用grid用戶登錄CentOS7_64_1,將zookeeper-3.4.6的安裝包下載傳至/home/grid目目錄下
http下載路徑: http://apache.fayea.com/zookeeper/
linux命令下載:$ wget
http://apache.fayea.com/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz
解壓安裝包
輸入tar -zxvf zookeeper-3.4.6.tar.gz將其解壓,如下:
創建data和logs目錄
解壓後進入zookeeper-3.4.6目錄,創建data目錄和logs目錄,zookeeper默認是不帶這兩個目錄的,需要用戶自行創建並指定。
[grid@h1 zookeeper-3.4.6]$ mkdir data
[grid@h1 zookeeper-3.4.6]$ mkdir logs
創建myid文件
在dataDir=/home/grid/zookeeper-3.4.6/data下創建myid文件
編輯myid文件,並在對應的IP的機器上輸入對應的編號。如在第一臺zookeeper上,我們給該myid文件內容指定就是1。如果只在單點上進行安裝配置,那麼只有一個server,後面講集羣的時候會有多態server故會有2,3,4…等等。
[grid@h1 data]$ vi myid 1
複製修改配置文件
接着進入zookeeper-3.4.6/conf目錄下,將zoo_sample.cfg文件複製一份取名zoo.cfg
[grid@h1 conf]$ cp zoo_sample.cfg zoo.cfg
注:之所以取名zoo.cfg是因爲這是啓動時默認約定讀取的
server.1=h1:2888:3888的解釋如下:
1是指一個數字,與前面創建的myid對應即可,標誌這是第幾臺機器,h1是我配置的映射名,大家可以直接將h1改爲自己的ip,如server.1=192.168.2.101:2888:3888;
Hosts映射配置:vi /etc/hosts,輸入自己的ip對應寫個名字即可,與windows類似,此配置步驟可以忽略,直接在zookeeper下的zoo.cfg文件寫ip地址即可
2888 表示的是這個服務器與集羣中的 Leader 服務器交換信息的端,2888端口簡單來說就是zookeeper服務之間的通信端口;
3888端口是zookeeper與其他應用程序通信的端口
其他cfg參數說明
tickTime=2000
tickTime這個時間是作爲Zookeeper服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每個tickTime時間就會發送一個心跳。
initLimit=10
initLimit這個配置項是用來配置Zookeeper接受客戶端(這裏所說的客戶端不是用戶連接Zookeeper服務器的客戶端,而是Zookeeper服務器集羣中連接到Leader的Follower 服務器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過10個心跳的時間(也就是tickTime)長度後Zookeeper 服務器還沒有收到客戶端的返回信息,那麼表明這個客戶端連接失敗。總的時間長度就是10*2000=20 秒。
syncLimit=5
syncLimit這個配置項標識Leader與Follower之間發送消息,請求和應答時間長度,最長不能超過多少個tickTime的時間長度,總的時間長度就是5*2000=10秒。
dataDir=/home/grid/zookeeper-3.4.6/data
dataDir顧名思義就是Zookeeper保存數據的目錄,默認情況下Zookeeper將寫數據的日誌文件也保存在這個目錄裏。
clientPort=2181
clientPort這個端口就是客戶端(應用程序)連接Zookeeper服務器的端口,Zookeeper會監聽這個端口接受客戶端的訪問請求
增加環境變量
修改該用戶下的.bash_profile文件,此文件默認爲隱藏的
[grid@h1 data]$ vi /home/grid/.bash_profile ,增加內容如下:
export ZOOKEEPER_HOME=/home/grid/zookeeper-3.4.6
export PATH=$ZOOKEEPER_HOME/bin:$PATH
使配置文件生效:
[grid@h1 data]$ source /home/grid/.bash_profile
防火牆配置
在防火牆中打開要用到的端口,一般默認是開放了22端口,所以我們才能使用遠程工具使用22進行連接,現在我們去配置2181 2888 3888端口,切換到root用戶執行如下命令
chkconfig iptables on設置開機啓動
service iptables start 啓動防火牆
我這裏設置時就報錯了,報錯咱就得解決
解決方案:執行yum install iptables-services下載安裝插件
安裝完成後再次執行chkconfig iptables on,service iptables start命令
接下來繼續開放防火牆端口
[root@h1 ~]# vi /etc/sysconfig/iptables
複製22端口那一行3次,然後將端口修改爲需要開放的3個,如下:
重啓防火牆
[root@h1 ~]# service iptables restart
開啓zookeeper服務
啓動並測試zookeeper(使用grid用戶啓動,不要使用root賬戶),在zookeeper目錄的bin下面執行
[grid@h1 bin]$ ./zkServer.sh start
執行jps查看狀態,其中QuorumPeerMain是zookeeper進程,啓動正常
查看zookeeper服務輸出信息,其日誌信息文件在
/home/grid/zookeeper-3.4.6/bin/zookeeper.out
[grid@h1 bin]$ tail -222f zookeeper.out查看
集羣模式
服務器CentOS7_64_1的ip:192.168.2.101
服務器CentOS7_64_2的ip:192.168.2.102
服務器CentOS7_64_3的ip:192.168.2.103
首先我們將另外兩臺也按照如上方式進行配置,首先保證每臺機器自己啓動zookeeper成功,配置好後我們現在是擁有3臺單機的zookeeper,那麼下面我們進行集羣的配置
hosts配置
首先修改3臺虛擬機的hosts映射配置:vi /etc/hosts,3臺機器分別加上自己ip和hosts別名的映射(修改後自動生效),如下:
修改防火牆端口
接下來配置3臺服務器的端口,防火牆那一塊改爲下面對應的端口
機器1—端口:2181,2881,3881
機器2—端口:2182,2882,3882
機器3—端口:2183,2883,3883
zookeeper配置
vi /conf/zoo.cfg,3臺機器注意注意端口號參數
修改data文件夾下的myid文件的值,分別對應的值爲1,2,3
啓動zookeeper
我啓動了第一臺服務出了如下異常,於是我想應該是防火牆的哪個配置未生效
異常信息:
Cannot open channel to 2 at election address h2/192.168.2.102:3882 java.net.NoRouteToHostException: 沒有到主機的路由
應該是防火牆配置改了未生效,於是重新啓動了3臺機器防火牆 service iptables restart,
下面是我重新啓動後拋出的異常
異常信息:
Cannot open channel to 1 at election address h1/192.168.2.101:3881 java.net.ConnectException: 拒絕連接
解決異常
一開始認爲是等待其他機器開啓,但啓動其他兩臺後一直出現該問題,所以花了半個小時查原因,後來檢查沒發現配置問題,但3臺機器的hosts文件中有如下內容,決定嘗試刪掉後重啓,果然正常啓動
127.0.0.1 localhost h1 localhost4 localhost4.localdomain4
::1 localhost h1 localhost6 localhost6.localdomain6
再次重啓成功
下圖這裏開始啓動出錯的原因是集羣環境正等待着另外幾臺機器,否則一臺也沒辦法進行選舉等操作,第二臺機器起來後就恢復正常了。
查看狀態
接下來我們運行status命令分別查看各自的狀態
啓動的第一臺機器:3號機-領導者
啓動的第二臺機器:2號機-跟隨者
啓動第三臺機器:1號機-跟隨者
設置服務爲開機啓動
配置zookeeper爲grid用戶開機啓動,不然在生產環境會很麻煩
編輯/etc/rc.local文件,加入: export JAVA_HOME=/usr/local/jdk #必須加,否則後面的java服務起不來
root外用戶啓動:
export JAVA_HOME=/usr/local/jdk su - grid -c ‘/home/grid/zookeeper-3.4.6/bin/zkServer.sh start’
root用戶啓動:
export JAVA_HOME=/usr/local/jdk ‘/home/grid/zookeeper-3.4.6/bin/zkServer.sh start
注:su – grid是指切換到grid用戶,-c是指調用後面命令
添加之後要確認下/etc/rc.local的是否有權限執行,默認是沒有權限執行的。
chmod +x /etc/rc.d/rc.local
重啓後發現/etc/rc.local能夠執行了。
高可用:一旦leader停止服務,剩下的follower會選舉出leader,大家可以嘗試下看看狀態變化