欢迎来到分布式管中窥豹之zookeeper小白学习系列,本系列会记录zookeeper以及分布式系统学习过程中的一些操作和细节,大饼果子非科班出身,如有错误,欢迎指出
本篇将启动zookeeper服务的仲裁模式,三个节点将以不同的端口号在本地被启动
1. 首先我们需要修改一下配置文件
节点1的配置文件z1.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/Users/dabingguozi/Documents/zookeeper/data/z1/data clientPort=2181 server.1=127.0.0.1:2222:2223 server.2=127.0.0.1:3333:3334 server.3=127.0.0.1:4444:4445
节点2的配置文件z2.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/Users/dabingguozi/Documents/zookeeper/data/z2/data clientPort=2182 server.1=127.0.0.1:2222:2223 server.2=127.0.0.1:3333:3334 server.3=127.0.0.1:4444:4445
节点3的配置文件z3.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/Users/dabingguozi/Documents/zookeeper/data/z3/data clientPort=2183 server.1=127.0.0.1:2222:2223 server.2=127.0.0.1:3333:3334 server.3=127.0.0.1:4444:4445
因为是本机的三个节点,所以需要不同的端口号
最后的三行是对节点的配置,server.n的n是服务的编号,我们会发现每个server配有两个端口号,前一个用于仲裁通信,后一个用于群首选举(涉及到分布式一致性算法,稍后会降到讲到)
2. 现在我们需要在dataDir的路径下指定节点的编号
echo 1 > /Users/dabingguozi/Documents/zookeeper/data/z1/data/myid echo 2 > /Users/dabingguozi/Documents/zookeeper/data/z2/data/myid echo 3 > /Users/dabingguozi/Documents/zookeeper/data/z3/data/myid
3. 启动服务
到z1的路径下启动
$ ./../../zookeeper-3.4.12/bin/zkServer.sh start ./z1.cfg
我们会发现他在尝试和其他节点通信,但是并没有成功(log在zookeeper.out文件中)
2019-01-29 10:40:14,968 [myid:1] - WARN [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:[email protected]] - Cannot open channel to 2 at election address /127.0.0.1:3334 java.net.ConnectException: Connection refused (Connection refused) at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:400) at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:243) at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:225) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:402) at java.base/java.net.Socket.connect(Socket.java:591) at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:558) at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectAll(QuorumCnxManager.java:610) at org.apache.zookeeper.server.quorum.FastLeaderElection.lookForLeader(FastLeaderElection.java:838) at org.apache.zookeeper.server.quorum.QuorumPeer.run(QuorumPeer.java:957) 2019-01-29 10:40:14,968 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:[email protected]] - Resolved hostname: 127.0.0.1 to address: /127.0.0.1 2019-01-29 10:40:14,969 [myid:1] - WARN [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:[email protected]] - Cannot open channel to 3 at election address /127.0.0.1:4445 java.net.ConnectException: Connection refused (Connection refused) at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:400) at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:243) at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:225) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:402) at java.base/java.net.Socket.connect(Socket.java:591)
再去到z2和z3的路径下分别启动服务
$ ./../../zookeeper-3.4.12/bin/zkServer.sh start ./z2.cfg $ ./../../zookeeper-3.4.12/bin/zkServer.sh start ./z3.cfg
那么我们再次观察log
2019-01-29 10:41:55,925 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:[email protected]] - FOLLOWING - LEADER ELECTION TOOK - 152007 2019-01-29 10:41:55,927 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumPeer$Qu[email protected]] - Resolved hostname: 127.0.0.1 to address: /127.0.0.1 2019-01-29 10:41:55,973 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:[email protected]] - Getting a diff from the leader 0x40000000a
z1已经成功的和z2还有z3完成通信了
4. 尝试连接
这次我们用z3的端口连接
$ ./zkCli.sh -server localhost:2183 Connecting to localhost:2183 2019-01-29 10:45:09,499 [myid:] - INFO [main:[email protected]] - Client environment:zookeeper.version=3.4.12-e5259e437540f349646870ea94dc2658c4e44b3b, built on 03/27/2018 03:55 GMT ......Welcome to ZooKeeper! 2019-01-29 10:45:09,536 [myid:] - INFO [main-SendThread(localhost:2183):[email protected]] - Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2183. Will not attempt to authenticate using SASL (unknown error) 2019-01-29 10:45:09,550 [myid:] - INFO [main-SendThread(localhost:2183):[email protected]] - Socket connection established to localhost/0:0:0:0:0:0:0:1:2183, initiating session JLine support is enabled 2019-01-29 10:45:09,604 [myid:] - INFO [main-SendThread(localhost:2183):[email protected]] - Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2183, sessionid = 0x300322ca7c90000, negotiated timeout = 30000 WATCHER:: WatchedEvent state:SyncConnected type:None path:null [zk: localhost:2183(CONNECTED) 0]
我们成功连接上了
那么让我们去看一下这三个节点的状态信息
$ ./../../zookeeper-3.4.12/bin/zkServer.sh status ./z1.cfg ZooKeeper JMX enabled by default Using config: ./z1.cfg Mode: follower $ ./../../zookeeper-3.4.12/bin/zkServer.sh status ./z2.cfg ZooKeeper JMX enabled by default Using config: ./z2.cfg Mode: leader $ ./../../zookeeper-3.4.12/bin/zkServer.sh status ./z3.cfg ZooKeeper JMX enabled by default Using config: ./z3.cfg Mode: follower
因为随机性,mode是leader的不一定是z2,但一定有一个节点是leader
这里就出现了这个概念,leader,follower,这是zookeeper仲裁模式下各个节点的角色(还有一个角色叫做observer)
之前的篇幅提到过zookeeper可以用来管理协同数据,那么这个管理的服务如果是单点的(像我们之前启动的独立模式),他的可用性就不高,也就是说,如果这个zookeeper节点宕机或者发生网络异常就没有办法再管理数据了。仲裁模式其实就是为解决这样的问题而提供的多节点协同服务,它也是一种分布式的服务。那么作为分布式的服务,为保证接入每一个节点拿到的数据都是一致的,就需要分布式的一致性协议去保证。
分布式的终极一致性协议paxos,本果子目前还没有甚解,但是zookeeper的ZAB(zookeeper atomic broadcast)协议,我们可以先一起学习一下
管中窥豹,可见一斑
那么下一篇就来研究一下这个ZAB协议吧
https://www.cnblogs.com/dabingguozi/p/10333110.html
原文地址:https://www.cnblogs.com/dabingguozi/p/10329411.html