我們首先准備三台服務器,IP地址分別如下(前提是要先安裝JDK)
192.168.100.101 192.168.100.102 192.168.100.103
1、配置主機名到IP地址的映射(此步驟不是必須的,我們可以直接在zk的配置文件中填寫IP地址),這樣配置的好處是如果某個IP地址發生了變化,我們不需要重啟zookeeper,直接修改主機對應的IP地址即可。
直接修改/etc/hosts文件,設置主機zoo-1映射到192.168.100.101,設置主機zoo-2映射到192.168.100.102,設置主機zoo-3映射到192.168.100.103
[root@localhost zookeeper]# vi /etc/hosts
然后在文件末尾追加
192.168.100.101 zoo-1 192.168.100.102 zoo-2 192.168.100.103 zoo-3
這里的映射關系,保存后立即生效的。
2、在其中一台機器上安裝zookeeper,下載zookeeper到zoo-1的機器上,此處使用的zookeeper-3.4.9,zookeeper下載解壓后,修改配置文件即可使用。
[root@localhost zookeeper]# tar zxvf /usr/local/download/zookeeper-3.4.9.tar.gz /usr/local/soft/zookeeper
進入conf目錄下,將zoo_sample.cfg復制一份重命名為zoo.cfg(zookeeper啟動時默認尋找conf下名字為zoo.cfg的配置文件)
[root@localhost zookeeper]# cd /usr/local/soft/zookeeper/zookeeper-3.4.9/ [root@localhost conf]# cp zoo_sample.cfg zoo.cfg
修改zoo.cfg中的配置信息
[root@localhost conf]# vi 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=/usr/local/data/zookeeper #zookeeper數據目錄 # 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 #設置集群信息,此處的zoo-x可以用ip地址代替 server.1=zoo-1:2888:3888 server.2=zoo-2:2888:3888 server.3=zoo-3:2888:3888
創建zookeeper的數據目錄,即我們zoo.cfg中的dataDir對應的目錄
[root@localhost conf]# mkdir /usr/local/data/zookeeper
在dataDir目錄中,創建一個名為myid的文件,並寫入機器對應的數字值,比如我們是在zoo-1的機器上,就將該值設置為1,即集群中sever.1=zoo-1:2888:3888中server.后對應的數字。這是zookeeper用來識別是那一台集群機器的標識。
[root@localhost conf]# echo "1" > /usr/local/data/zookeeper/myid
此時我們集群中的一台服務器就配置好了
3、在其余兩台機器上也安裝zookeeper,可以通過scp命令直接拷貝文件即可。每個機器的都是用相同的配置信息。
[root@localhost conf]# scp -r /usr/local/soft/zookeeper/zookeeper-3.4.9/ root@192.168.100.102:/usr/local/soft/zookeeper root@192.168.100.102's password:
輸入密碼即可將對應的文件傳輸到要其他集群機器上。
注:此處唯一不同的地方是每個dataDir下的myid中的內容要按照zoo.cfg配置文件中的集群信息設置。比如:192.168.100.102對應集群中的server.2,所以在myid中寫入2
到此為止,集群相關配置已經完畢了。下面就可以啟動集群了
4、啟動zookeeper集群
我的啟動順序是:zoo-1 -> zoo-2 --> zoo-3
[root@localhost zookeeper]# pwd /usr/local/soft/zookeeper [root@localhost zookeeper]# zookeeper-3.4.9/bin/zkServer.sh start ZooKeeper JMX enabled by default Using config: /usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../conf/zoo.cfg Starting zookeeper ... STARTED
這樣表明zoo-1的服務器已經啟動,同時在我們當前操作路徑下回生成一個zookeeper的日志文件,zookeeper.out
[root@localhost zookeeper]# pwd /usr/local/soft/zookeeper [root@localhost zookeeper]# ll 總用量 24 drwxr-xr-x. 10 1001 1001 4096 8月 23 2016 zookeeper-3.4.9 -rw-r--r--. 1 root root 19350 10月 27 23:54 zookeeper.out
文件中記錄了集群的日志信息,當只啟動zoo-1服務器的時候,日志中會出現異常,應為集群其他服務沒啟動,所以這個異常是沒問題的。大概信息如下
[root@localhost zookeeper]# tailf zookeeper.out at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:381) at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectAll(QuorumCnxManager.java:426) at org.apache.zookeeper.server.quorum.FastLeaderElection.lookForLeader(FastLeaderElection.java:843) at org.apache.zookeeper.server.quorum.QuorumPeer.run(QuorumPeer.java:822) 2017-10-27 23:35:29,886 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumPeer$QuorumServer@149] - Resolved hostname: zoo-3 to address: zoo-3/192.168.100.103 2017-10-27 23:35:29,886 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:FastLeaderElection@852] - Notification time out: 3200 2017-10-27 23:35:33,088 [myid:1] - WARN [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumCnxManager@400] - Cannot open channel to 2 at election address zoo-2/192.168.100.102:3888 java.net.ConnectException: 拒絕連接 (Connection refused) at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:381) at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectAll(QuorumCnxManager.java:426) at org.apache.zookeeper.server.quorum.FastLeaderElection.lookForLeader(FastLeaderElection.java:843) at org.apache.zookeeper.server.quorum.QuorumPeer.run(QuorumPeer.java:822) 2017-10-27 23:35:33,089 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumPeer$QuorumServer@149] - Resolved hostname: zoo-2 to address: zoo-2/192.168.100.102 2017-10-27 23:35:33,091 [myid:1] - WARN [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumCnxManager@400] - Cannot open channel to 3 at election address zoo-3/192.168.100.103:3888
接着啟動zoo-2和zoo-3,全部啟動完畢后,集群會自動選舉出一台服務器作為leader,其余服務器為follower。
可以在每台服務器上使用命令查看服務器是什么類型的:
[root@zoo-1 zookeeper]# zookeeper-3.4.9/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: follower
[root@zoo-2 zookeeper]# zookeeper-3.4.9/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: leader
[root@zoo-3 zookeeper]# zookeeper-3.4.9/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../conf/zoo.cfg Mode: follower
通過上面狀態查詢結果可見,zoo-2是集群的Leader,其余的兩個結點是Follower。可以通過客戶端,連接到ZooKeeper集群上。對於客戶端來說,ZooKeeper是一個整體(ensemble),你可以在任何一個結點上建立到服務集群的連接,例如:
[root@localhost zookeeper]# zookeeper-3.4.9/bin/zkCli.sh -server 192.168.100.101:2181 Connecting to 192.168.100.101:2181 2017-10-28 01:24:49,345 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.9-1757313, built on 08/23/2016 06:50 GMT 2017-10-28 01:24:49,350 [myid:] - INFO [main:Environment@100] - Client environment:host.name=localhost 2017-10-28 01:24:49,350 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.8.0_151 2017-10-28 01:24:49,358 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation 2017-10-28 01:24:49,358 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/usr/local/soft/java/jdk1.8.0_151/jre 2017-10-28 01:24:49,359 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=/usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../build/classes:/usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../build/lib/*.jar:/usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../lib/slf4j-log4j12-1.6.1.jar:/usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../lib/slf4j-api-1.6.1.jar:/usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../lib/netty-3.10.5.Final.jar:/usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../lib/log4j-1.2.16.jar:/usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../lib/jline-0.9.94.jar:/usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../zookeeper-3.4.9.jar:/usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../src/java/lib/*.jar:/usr/local/soft/zookeeper/zookeeper-3.4.9/bin/../conf: 2017-10-28 01:24:49,359 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib 2017-10-28 01:24:49,359 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=/tmp 2017-10-28 01:24:49,359 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=<NA> 2017-10-28 01:24:49,359 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Linux 2017-10-28 01:24:49,359 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=amd64 2017-10-28 01:24:49,359 [myid:] - INFO [main:Environment@100] - Client environment:os.version=3.10.0-693.el7.x86_64 2017-10-28 01:24:49,359 [myid:] - INFO [main:Environment@100] - Client environment:user.name=root 2017-10-28 01:24:49,359 [myid:] - INFO [main:Environment@100] - Client environment:user.home=/root 2017-10-28 01:24:49,359 [myid:] - INFO [main:Environment@100] - Client environment:user.dir=/usr/local/soft/zookeeper 2017-10-28 01:24:49,360 [myid:] - INFO [main:ZooKeeper@438] - Initiating client connection, connectString=192.168.100.101:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@67424e82 2017-10-28 01:24:49,400 [myid:] - INFO [main-SendThread(192.168.100.101:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server 192.168.100.101/192.168.100.101:2181. Will not attempt to authenticate using SASL (unknown error) Welcome to ZooKeeper! JLine support is enabled 2017-10-28 01:24:49,544 [myid:] - INFO [main-SendThread(192.168.100.101:2181):ClientCnxn$SendThread@876] - Socket connection established to 192.168.100.101/192.168.100.101:2181, initiating session 2017-10-28 01:24:49,560 [myid:] - INFO [main-SendThread(192.168.100.101:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server 192.168.100.101/192.168.100.101:2181, sessionid = 0x15f5ed84b260001, negotiated timeout = 30000 WATCHER:: WatchedEvent state:SyncConnected type:None path:null [zk: 192.168.100.101:2181(CONNECTED) 0] ls / [zookeeper]