官网下载地址:[http://mirror.bit.edu.cn/apache/zookeeper/](http://mirror.bit.edu.cn/apache/zookeeper/)<br /> zookeeper 集群通常是用来对用户的分布式应用程序提供协调服务的,为了保证数据的一致性,对 zookeeper 集群进行了这样三种角色划分:leader、follower、observer分别对应着总统、议员和观察者。
- 总统(leader):负责进行投票的发起和决议,更新系统状态。
- 议员(follower):用于接收客户端请求并向客户端返回结果以及在选举过程中参与投票。
观察者(observer):也可以接收客户端连接,将写请求转发给leader节点,但是不参与投票过程,只同步leader的状态。通常对查询操作做负载。
我们知道,在每台机器数据保持一致的情况下,zookeeper集群可以保证,客户端发起的每次查询操作,集群节点都能返回同样的结果。但是对于客户端发起的修改、删除等能改变数据的操作呢?集群中那么多台机器,你修改你的,我修改我的,最后返回集群中哪台机器的数据呢?<br /> 这就是一盘散沙,需要一个领导,于是在zookeeper集群中,leader的作用就体现出来了,只有leader节点才有权利发起修改数据的操作,而follower节点即使接收到了客户端发起的修改操作,也要将其转交给leader来处理,leader接收到修改数据的请求后,会向所有follower广播一条消息,让他们执行某项操作,follower 执行完后,便会向 leader 回复执行完毕。当 leader 收到半数以上的 follower 的确认消息,便会判定该操作执行完毕,然后向所有 follower 广播该操作已经生效。<br /> 所以zookeeper集群中leader是不可缺少的,但是 leader 节点是怎么产生的呢?其实就是由所有follower 节点选举产生的,讲究民主嘛,而且leader节点只能有一个,毕竟一个国家不能有多个总统。<br /> 一写多读Leader写,Follower只能读
下载安装并修改配置文件
此时我们按照安装三个节点,对下载好的zk文件夹复制成三分,对其中cong目录下将 zoo_sample.cfg 文件复制并重命名为 zoo.cfg 文件。然后通过
第一份配置文件配置情况
tickTime=2000
initLimit=10
syncLimit=5
dataLogDir=/Users/humingming/hmm/zklogDir
dataDir=/Users/humingming/hmm/zkdataDir
clientPort=2181
#集群搭建
server.1=192.168.0.102:2881:3881
server.2=192.168.0.102:2881:3882
server.3=192.168.0.102:2881:3883
第二份配置文件配置情况
tickTime=2000
initLimit=10
syncLimit=5
dataLogDir=/Users/humingming/hmm/zklogDir2
dataDir=/Users/humingming/hmm/zkdataDir2
clientPort=2182
#集群搭建
server.1=192.168.0.102:2881:3881
server.2=192.168.0.102:2881:3882
server.3=192.168.0.102:2881:3883
第三份配置文件配置情况
tickTime=2000
initLimit=10
syncLimit=5
dataLogDir=/Users/humingming/hmm/zklogDir3
dataDir=/Users/humingming/hmm/zkdataDir3
clientPort=2183
#集群搭建
server.1=192.168.0.102:2881:3881
server.2=192.168.0.102:2881:3882
server.3=192.168.0.102:2881:3883
修改客户端开放端口和节点数据存放地址和日志运行日志存放地址:
①、tickTime:基本事件单元,这个时间是作为Zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,每隔tickTime时间就会发送一个心跳;最小 的session过期时间为2倍tickTime
②、dataDir:存储内存中数据库快照的位置,除非另有说明,否则指向数据库更新的事务日志。注意:应该谨慎的选择日志存放的位置,使用专用的日志存储设备能够大大提高系统的性能,如果将日志存储在比较繁忙的存储设备上,那么将会很大程度上影像系统性能。
③、client:监听客户端连接的端口。
④、initLimit:允许follower连接并同步到Leader的初始化连接时间,以tickTime为单位。当初始化连接时间超过该值,则表示连接失败。
⑤、syncLimit:表示Leader与Follower之间发送消息时,请求和应答时间长度。如果follower在设置时间内不能与leader通信,那么此follower将会被丢弃。
⑥、server.A=B:C:D
- server.A=B:C:D中的A是一个数字,表示这个是第几号服务器,
- B是这个服务器的IP地址
- C第一个端口用来集群成员的信息交换,表示这个服务器与集群中的leader服务器交换信息的端口,也是Leader选举的端口
D是在leader挂掉时专门用来进行选举leader所用的端口(Zookeeper服务器之间的通信端口。)
讲的通俗点就是第二C端口号是领导这的端口号,是小弟同步数据连接大哥开辟的端口号;D端口号是选举使用的端口号,大哥挂了,小弟重新选举所需端口号。
创建myid文件
在我们的dataDir目录下创建myid文件并配置上我们配置文件中你节点的id,我这里是1 2 3
启动zk
分别启动三台zk服务<br />第一台:<br />bin目录下启动 ./zkServer.sh start<br />检查zk是否启动 ./zkServer.sh status 一般会返回你是主从或者standalone单节点<br />cli连接zk ./zkCli.sh -server 192.168.0.102:2181<br />第二台:<br />bin目录下启动 ./zkServer.sh start<br />cli连接zk ./zkCli.sh -server 192.168.0.102:2182<br />第三台:<br />bin目录下启动 ./zkServer.sh start<br />cli连接zk ./zkCli.sh -server 192.168.0.102:2183<br />下面截图左半部分为我启动zk时控制台输出信息:<br />![屏幕快照 2020-03-21 上午9.35.56.png](https://cdn.nlark.com/yuque/0/2020/png/771792/1584754625302-60be0441-3395-4b65-80fb-ae8324291441.png#align=left&display=inline&height=1390&name=%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202020-03-21%20%E4%B8%8A%E5%8D%889.35.56.png&originHeight=1390&originWidth=2559&size=629974&status=done&style=none&width=2559)
选举算法
每当发起者接收到其它的被推举者,我都要回馈一个信息,表明我还是不是推举我自己。如果被推举者没我大,我就一直推举我当leader,是我是我还是我!一旦我不再推举我自己了(这时我发现别人推举的人比我推荐的更牛),我就把我的票箱清空,重新发起一轮投票(这时我的票箱一定有两票了,都是选的我认为最牛的人)。
- 每个服务实例发起选举自己为领导者的投票
- 其他实例收到投票邀请,比较发起者的事物ID zxid是否比自己最新的事物ID大,大则投一票,小则不投它,相等则比较发起服务器的ID,大则投给它;
- 发起者收到大家的投票,看到票数(包含自己)是否大于集群的半数,大于则成为leader,小于且领导者未被选出则再次发起投票。
举例:假设服务器ID分别是1、2、3、4、5依次启动。
- 服务器1启动给自己投票,然后发起投票信息,由于其它机器还没启动不会反馈信息,所以服务器1不会收到反馈信息,所以服务器1会处于Locking状态
- 服务器2启动,给自己投票,同时与服务器1交换结果,由于服务器2的编号比服务器1大,则给自己投票,服务器1也就倒戈相向。但此时投票数没有大于半数,所以两个服务器均是Locking状态
- 服务器3启动,给自己投票同时与服务器1 2交换投票信息,由于服务器3的编号大于二者,此时投票数正好大于半数所以服务器3成为领导。服务器1 2则成为小弟
- 服务器4启动,给自己投票,同时交换前三台服务器投票信息,尽管服务器4编号大,但之前服务器3已经生出,所以此是它已经无法改变战局
- 服务器5启动,后面逻辑同4