Zookeeper
补充
- CountDownLatch:闭锁。会对线程进行计数,在计数归零之前,之前的线程会被阻塞;当计数归零之后,被阻塞的线程就会自动放开继续执行
- CyclicBarrier:栅栏。会对线程进行计数,在计数归零之前,之前的线程会被阻塞;当计数归零之后,被阻塞的线程就会自动放开继续执行
安装(集群模式)
安装JDK
-
三个节点删除Linux自带的JDK
rpm -qa | grep -i jdk | xargs rpm -ev --nodeps
-
创建对应的目录
cd /opt mkdir presoftware mkdir software
-
在第一个节点上传JDK
cd presoftware/ # 上传JDK rz # 如果没有找到命令,那么安装之后重新上传 yum -y install lrzsz
-
解压
tar -xvf jdk-8u371-linux-x64.tar.gz -C ../software/
-
重命名
cd ../software/ mv jdk1.8.0_371/ jdk1.8
-
远程拷贝
# 回到/opt目录下 cd .. scp -r software/ root@10.16.2.194:/opt scp -r software/ root@10.16.2.193:/opt
-
配置环境变量
# 编辑文件 vim /etc/profile.d/javahome.sh # 如果找不到vim yum -y install vim # 添加环境变量 export JAVA_HOME=/opt/software/jdk1.8 export PATH=$PATH:$JAVA_HOME/bin # 保存退出,生效 source /etc/profile.d/javahome.sh # 测试 javac -version java -version
-
远程拷贝
scp /etc/profile.d/javahome.sh root@10.16.2.194:/etc/profile.d/ scp /etc/profile.d/javahome.sh root@10.16.2.193:/etc/profile.d/
-
测试其他两个节点的
javac
和java
能否使用,如果不能,那么就先source
之后再次测试
安装Zookeeper
-
进入预安装目录,上传Zookeeper的安装包
cd /opt/presoftware/ # 上传安装包 rz
-
解压
tar -xvf apache-zookeeper-3.9.1-bin.tar.gz -C /opt/software/
-
重命名
cd ../software/ mv apache-zookeeper-3.9.1-bin/ zookeeper-3.9.1
-
进入Zookeeper的配置目录
cd zookeeper-3.9.1/conf/
-
复制文件
cp zoo_sample.cfg zoo.cfg
-
编辑文件
vim zoo.cfg
修改
dataDir
属性的值dataDir=/opt/software/zookeeper-3.9.1/data
在文件末尾添加
server.编号=IP或者主机名:原子广播端口:选举端口
,例如# 编号要求不能重复,必须是正整数 server.1=10.16.2.191:2888:3888 server.2=10.16.2.194:2888:3888 server.3=10.16.2.193:2888:3888
-
构建数据目录并进入
mkdir /opt/software/zookeeper-3.9.1/data cd /opt/software/zookeeper-3.9.1/data
-
编辑文件,文件名固定为
myid
vim myid
在文件中添加当前主机的编号
-
远程拷贝
cd /opt/software/ scp -r zookeeper-3.9.1/ root@10.16.2.194:$PWD scp -r zookeeper-3.9.1/ root@10.16.2.193:$PWD
-
修改对应主机的myid
vim /opt/software/zookeeper-3.9.1/data/myid
修改为对应主机的myid,例如第二台主机的myid为2,第三台主机的myid为3
-
配置环境变量
# 编辑文件 vim /etc/profile.d/zookeeperhome.sh # 在文件中添加 export ZOOKEEPER_HOME=/opt/software/zookeeper-3.9.1 export PATH=$PATH:$ZOOKEEPER_HOME/bin # 保存退出,生效 source /etc/profile.d/zookeeperhome.sh
-
远程拷贝
scp /etc/profile.d/zookeeperhome.sh root@10.16.2.194:/etc/profile.d scp /etc/profile.d/zookeeperhome.sh root@10.16.2.193:/etc/profile.d
-
另外两个节点上进行source
source /etc/profile.d/zookeeperhome.sh
-
启动Zookeeper
zkServer.sh start
-
查看Zookeeper的状态
zkServer.sh status
如果出现一个leader+2个follower,那么说明配置成功
选举机制
概述
- 当Zookeeper集群启动的时候,此时所有的节点(在集群中,节点指的就是服务器)都会进入选举状态,并且此时所有的节点都会推荐自己成为leader
- 当一个节点收到别人的选举信息之后,就会进行比较。经过多轮比较之后,最后胜出的节点会成为leader
选举细节
- 在Zookeeper集群中,当出现没有leader(集群刚刚启动,或者是leader宕机)的状态时,此时整个集群的所有节点都会进入选举状态,准备选举
- Zookeeper会为每一次选举出来的leader分配一个递增的编号,称之为Epochid
- 选举信息
- leader编号(Epochid)。如果Epochid比较小,那么说明操作已经过时
- 最大事务id(Zxid)。Zxid越大,说明这个节点接收的写操作越多
- 选举编号(myid)。要求myid不能重复
- 比较原则
- 先比较两个节点的Epochid,谁大谁赢
- 如果Epochid一致,那么比较两个节点的最大事务id,谁大谁赢
- 如果最大事务id一致,那么比较myid
- 如果两个节点进行比较,一方失败,那么失败的节点会转而接受胜出的节点的选举信息,此时可以理解为胜出的节点获得了一票。当一个节点赢得半数及以上的节点的支持的时候,那么这个节点就会成为leader - 过半性
- 如果一个Zookeeper集群中已经存在了leader,那么新添的节点的事务id或者myid无论是多少,只能成为follower
- 如果leader产生宕机,那么Zookeeper集群会重新选举出一个新的leader
- 一个节点能否成为leader,看这个节点能否抢先过半
- 在Zookeeper集群中,如果出现了2个及以上的leader,这种现象称之为脑裂
- 产生脑裂的原因
- 集群产生了分裂 - 硬件故障、网络故障等都会产生分裂,这个问题无法避免
- 分裂之后还进行了选举
- 在Zookeeper集群中,如果存活(能够相互通信)的节点个数不足一半,无论leader是否存在,剩余的存活节点都会停止服务(对外停止接收请求,对内停止选举和原子广播) - 过半性
- 如果集群中存在两个及以上的leader,那么此时会比较leader之间的Epochid。Epochid较小的节点就会变为follower状态
- 在集群的选举期间,集群只对外提供读服务,不提供写服务!
- Zookeeper集群中的节点状态
- voting/looking:选举状态
- follower:追随者/跟随者
- leader:领导者
- observer:观察者
- leader和follower都是有决策权和执行权的节点,observer没有决策权,只有执行权