半数机制:集群中半数以上机器存活,集群可用,所以zookeeper适合在奇数台机器上,zookeeper虽然在配置文件没有说master/slave,zookeeper工作是一个节点为leader,其他的为follow,leader是选举出来的(内部有选举机制)
2、Zookeeper的第一次启动的选举 服务器初始化拿三台服务器组成的zookeeper集群为例,各自的myid为1-3,它们都是最新启动的,之前没有历史数据,看看它们之间的选举是咋样的,下图是依次启动
(1)服务器Server1启动,发起一次选举。服务器Server1投自己一票,此时服务器Server1票数1票,不够半数以上(3/2 + 1 =2),选举无法完成,服务器Server1状态为LOOKING
(2)服务器Server2启动,再次发起一次选举。服务器Server1和服务器Server2分别投自己一票,并且交换投票信息,此时服务器Server1发现服务器Server2的myid比自己的(服务器Server1)的myid大,更改选票为推举服务器Server2(把自己的票数给服务器Server2),此时服务器Server1和服务器Sever2票数为0,2,票数超过一半以上,服务Server2当选Leader,服务器Server1为following,服务器Server2为leader
(3)服务器Server3启动,发起一次选举。这时服务器Server1和服务器Server2状态分别为following、Leading,不会更改选票的信息(因为已经选出Leader,不在观察myid大小)服务器Server3为following(小弟)
注意:当集群服务器有5台时,前面的服务器1和服务器2,都是LOOKING,服务器1票数为0,服务器2票数为2,当启动第三台服务器时,服务器3的myid大,服务器2会把票数给服务器3,(服务器启动会给自己投一票)这时服务器3票数为3选为Leader,其他的都是following,之后启动的服务器也是following
2.2、zookeeper选举机制中的概念1)服务器状态
- LOOKING:选举中,正在寻找Leader
- FOLLOWING:随从状态,同步leader状态,参与投票
- Leader:领导者,差不多是master,在zookeeper中只有leader才有写的权限,following只有读的权限
- OBSERVING:观察者状态,不同leader状态,不参与投票
FOLLOWING状态主要具备以下几个功能: - 向leader发送请求(PING消息、request消息、ACK消息,RevalIDATE消息)
- 接收leader消息并处理
- 接收client发送过来的请求,如果为写请求,会发送给Leader进行投票处理,然后返回client结果
2)ServerId:服务器ID 和服务器的myid一致
比如有三台服务器,编号分别是1,2,3(myid里面的值)编号越大在选择算法中的权重越重
3)Zxid:事务ID
服务器中存放的最大数据ID;值越大说明数据越新,在选举算法中数据越新权重越大
用来标识一次服务器状态的变更.,在某个时刻集群中的每台机器的Zxid的值不一定完全一致,这个和zookeeper服务器对于客户端的更新的请求的逻辑有关了
4)Epoch:逻辑时钟
每个Leader任期的代号。或者可以叫投票的次数,没有Leader时统一轮投票过程中的逻辑时钟值相同的,每投完一次票这个数据就会增加,然后与接收到的其他的服务器返回的投票信息中的数值相比,根据不同的值做出不同的判断。
这时服务器(无法和leader保持连接的)会发起选举流程,当前集群可能会处于以下两种状态:
集群中本来存在leader或者集群中确实不存在leader
集群中存在leader,就是,它无法连接上leader而已,所以它(无法连接leader的服务器)发起leader选举
处理:会被告知当前服务器的leader的信息,对于该机器来说,仅仅需要和leader机器建立连接,并进行状态同步即可
三台服务器集群案例:
注意:首先必须安装好jdk
1)解压安装 在对应的目录下,比如:/usr/local/software
tar -zxvf apache-zookeeper-3.7.0-bin.tar.gz
修改目录为zookeeper:
mv apache-zookeeper-3.7.0 jdk
2)在/usr/local/software/zookeeper目录下创建一个zkData目录和log目录,并在zkData下创建myid文件,写入Server号
mkdir zkdata mkdir log # 在zkData创建myid文件,写入Server号 比如2 vim myid
注意:上下不要有空行,左右不要有空格
3)将zookeeper目录下的conf的zoo_sample.cfg 修改为 zoo.cfg,并对配置信息修改
# 修改名称 mv zoo_sample.cfg zoo.cfg # 打开并且配置信息 vim zoo.cfg # 配置信息 dataDir=/usr/local/software/zookeeper/zkData dataLogDir=usr/local/software/zookeeper/log
4)增加如下配置 集群信息
server.2=192.168.43.131:2888:3888 server.3=192.168.43.131:2888:3888 server.4=192.168.43.131:2888:3888
参数解读:
server.A=B:C:D
A是一个数字,表示这个是第几号服务器(myid的值)
集群模式下配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面有一个数据
就是 A 的值,Zookeeper 启动时读取此文件(myid),拿到里面的数据与 zoo.cfg 里面的配置信息比
较从而判断到底是哪个 server
B:是这个服务器的地址
C:是这个服务器Follow与集群中的leader服务器的交换信息端口号
D:是万一集群中的leader服务器挂了,需要一个端口来重新进行选举,选出一个新的leader,而这个端口就是用来执行选举时服务器相互通信的端口
为什么可以一样:因为在三台服务器上,端口不会冲突(要是伪集群,就会出现端口占用情况)
在三台配置中都配置以上信息,就可以了
5) 分别启动Zookeeoper
bin/zkServer.sh start
【说明】:zoo.cfg的配置信息的详细介绍
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/tmp/zookeeper clientPort=2181
tickTime:zookeeper的时间单位,单位是ms,就是2s,后面的时间都是以tickTime为基础单位
initLimt:允许follower连接并且同步Leader的初始化连接时间(10*2000ms)
syncLimit:允许Leader与follower之间发消息和应答时间限制【数据同步】(超过这时间就认为follower掉线不等)
dataDir:存储zookeeper数据和日志路径
clientPort:客户端连接服务器端口(默认是2181)



