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,大家可以嘗試下看看狀態變化