zookeeper集群搭建
kafka是把狀態保存在zookeeper中的,首先要搭建zookeeper集群。盡管kafka本身自帶了zookeeper,但最好不要使用自帶的zookeeper。參考這兩個教程: 教程一(三臺虛擬機),教程二(兩臺虛擬機)。
1.軟件環境
我用了三臺虛擬機作為服務器,虛擬機裝的是CentOS7 64位:
- 192.168.172.10
- 192.168.172.11
- 192.168.172.12
-
Linux服務器。使用數量為一臺,三臺,五臺,(2*n+1)。zookeeper集群的工作是超過半數才能對外提供服務,三臺中超過兩臺超過半數,允許一臺掛掉。最好不要使用偶數臺。
例如:如果有4臺,那么掛掉一臺還剩下三臺,如果再掛掉一臺就不能行了,因為是要超過半數。
Java jdk1.8. 因為zookeeper是用Java寫的,所以他需要Java環境,CentOS 7默認安裝了jdk,所以此處不在安裝。
zookeeper3.4.11版。
2.配置與安裝zookeeper。
下面的操作是三臺虛擬機都要做的,并且除了特別指出的,其他部分三臺虛擬機所做的配置操作是完全相同的
2.1安裝Java
CentOS7自帶jdk,此處無需安裝。
2.2下載zookeeper
首先要注意的是在生產環境中目錄結構要定義好,防止在項目過多的時候找不到所需的項目。 我把目錄統一放在/opt下面,該目錄一般存放主機額外安裝的軟件。
// 首先創建zookeeper項目目錄
mkdir zookeeper // 項目目錄
cd zookeeper // 進入項目目錄
mkdir zkdata // 存放快照日志
mkdir zkdatalog // 存放事物日志
從官網下載最新的穩定版zookeeper后,通過xshell的文件傳輸工具傳送到虛擬機中。我就放在了/opt/zookeeper項目文件下。
cd /opt/zookeeper // 進入下載目錄
tar -zxvf zookeeper-3.4.11.tar.gz // 解壓文件
2.3 修改配置文件
進入到解壓好的zookeeper的conf目錄中,查看:
//進入conf目錄
cd /opt/zookeeper/zookeeper-3.4.11/conf
//查看
-rw-rw-r--. 1 1000 1000 535 Feb 20 2014 configuration.xsl
-rw-rw-r--. 1 1000 1000 2161 Feb 20 2014 log4j.properties
-rw-rw-r--. 1 1000 1000 922 Feb 20 2014 zoo_sample.cfg
zoo_sample.cfg這個文件是官方給我們的zookeeper的樣板文件。我們需要復制一份名為zoo.cfg的文件,zoo.cfg是zookeeper官方指定的文件命名規則。我們以在第一臺虛擬機上的操作為例(上面的操作都是在第一臺虛擬機上,你需要在每臺虛擬機上都執行上述以及本次操作):
// 復制zoo.cfg文件
cp zoo_sample.cfg zoo.cfg
// 打開zoo.cfg文件,然后按后面的配置信息進行配置
vim zoo.zfg
在zoo.cfg配置文件需要填入的信息。
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/zookeeper/zkdata
dataLogDir=/opt/zookeeper/zkdatalog
clientPort=12181
// 此處的IP就是你所操作的三臺虛擬機的IP地址,每臺虛擬機的zoo.cfg中都需要填入這三個地址。第一個端口是master和slave之間的通信端口,默認是2888,第二個端口是leader選舉的端口,集群剛啟動的時候選舉或者leader掛掉之后進行新的選舉的端口默認是3888
server.1=192.168.172.10:12888:13888
server.2=192.168.172.11:12888:13888
server.3=192.168.172.12:12888:13888
// server.1 這個1是服務器的標識也可以是其他的數字, 表示這個是第幾號服務器,用來標識服務器,這個標識要寫到快照目錄下面myid文件里
創建myid文件。以現在所在的第一臺虛擬機192.168.172.10為例,對應server.1,通過上邊的配置信息可以查到。創建myid文件的目的是為了讓zookeeper知道自己在哪臺服務器上,例如現在所在的虛擬機是192.168.172.10,它對應的id是1,那么就在myid文件中寫入1.
echo "1" > /opt/zookeeper/zkdata/myid
另外兩臺虛擬機上也需要創建myid文件并寫入相應的id,id根據zoo.cfg文件中的IP地址查詢。
echo "2" > /opt/zookeeper/zkdata/myid
echo "3" > /opt/zookeeper/zkdata/myid
2.4 啟動zookeeper
進入到zookeeper的bin目錄下
cd /opt/zookeeper/zookeeper-3.4.11/bin/
// 啟動服務 (注意!三臺虛擬機都要進行該操作)
./zkServer.sh start
// 檢查服務器狀態
./zkServer.sh status
// 顯示如下
JMX enabled by default
Using config: /opt/zookeeper/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: follower #他是主節點leader還是從節點follower
3.重要配置說明(待補充)
- myid文件和server.myid 在快照目錄下存放的標識本臺服務器的文件,他是整個zk集群用來發現彼此的一個重要標識。
- zoo.cfg配置文件。zoo.cfg文件是zookeeper配置文件,在conf目錄里。
// tickTime:
這個時間是作為 Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。
// initLimit:
這個配置項是用來配置 Zookeeper 接受客戶端(這里所說的客戶端不是用戶連接 Zookeeper 服務器的客戶端,而是 Zookeeper 服務器集群中連接到 Leader 的 Follower 服務器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過 5個心跳的時間(也就是 tickTime)長度后 Zookeeper 服務器還沒有收到客戶端的返回信息,那么表明這個客戶端連接失敗??偟臅r間長度就是 52000=10 秒
// syncLimit:
這個配置項標識 Leader 與Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是52000=10秒
// dataDir:
快照日志的存儲路徑
// dataLogDir:
事物日志的存儲路徑,如果不配置這個那么事物日志會默認存儲到dataDir制定的目錄,這樣會嚴重影響zk的性能,當zk吞吐量較大的時候,產生的事物日志、快照日志太多
// clientPort:
這個端口就是客戶端連接 Zookeeper 服務器的端口,Zookeeper 會監聽這個端口,接受客戶端的訪問請求。修改他的端口改大點
4.遇到的錯誤
在搭建完成后,三個虛擬機都出現了錯誤。有兩個問題。
4.1 節點無法運行
在用./zkServer.sh start
命令運行zookeeper后,zookeeper節點顯示正常啟動,但是用zkServer.sh status
命令查看zookeeper節點的狀態時,發現并沒有正常運行,出現:
Error contacting service. It is probably not running.
我試著重新./zkServer.sh start
,卻無法啟動,顯示:
already running as process 11854
對于這個問題,網上有很多答案,試了一遍:
- zoo.cfg配置文件中指定目錄卻沒有創建! 創建相應目錄即可。
//我的目錄配置沒有問題 - zoo.cfg中dataDir指定路徑為Myid文件的路徑。Myid內容與:
server.?=192.168.172.10:12888:13888
中所設置?
是否一致?
//我的設置是一致的! - 使用
service iptables stop
關閉防火墻.
//這個確實沒關,但用的命令不是service iptables stop
,而是:
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall開機啟動
關閉后確實起作用了,但是第二天重新啟動時,剛開始運行還沒問題,到中午吃完飯回來就又出現了,所以應該不是防火墻的問題:
Error contacting service. It is probably not running.
- 打開zkServer.sh 找到
status)
STAT=echo stat | nc localhost $(grep clientPort "$ZOOCFG" | sed -e 's/.*=//') 2> /dev/null| grep Mode
在nc
與localhost
之間加上 -q 1
(是數字1
而不是字母l
).如果已存在則去掉。
// 但是我的zkServer.sh中沒有這一行。
- 12181端口被占用
使用netstat -anp | grep 12181
查看,確實發現有程序占用這個端口,但是kill掉以后還是不能啟動zookeeper。
于是我不再管虛擬機1,又依次開啟虛擬機2 和虛擬機3,其中虛擬機2和虛擬機1一樣,都是:
Error contacting service. It is probably not running.
但是神奇的事情發生了,我開啟虛擬機3的時候,是成功的,值得注意的是這里顯示的zookeeper狀態時leader:
[root@localhost bin]# ./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/zookeeper-3.4.11/bin/../conf/zoo.cfg
Mode: leader
也就是說虛擬機3所在的zookeeper節點是leader,然后再開啟虛擬機2和虛擬機1,就沒問題了。但是不知道為什么虛擬機3默認為leader,可能我之前在哪里配置過我不記得了(可能性不大),也可能跟zookeeper選舉leader的機制有關系,這個需要深入了解。
成功運行后,三臺虛擬機,一臺是leader,另外兩臺是follower。
4.2 每個節點都是standalone的
這個問題是由于zoo.cfg文件中的server
寫錯了,寫成了servers
。所以server
寫錯可能導致zookeeper運行在單機模式下。