Zookeeper集群搭建
一、zookeeper集群介绍
zookeeper集群的目的是为了保证系统的性能承载更多的客户端连接设专门提供的机制。
通过集群可以实现以下功能:
- 读写分离:提高承载,为更多的客户端提供连接,并保障性能。
- 主从自动切换:提高服务容错性,部分节点故障不会影响整个服务集群。
因为 zookeeper 通过判断大多数节点的存活来判断整个集群是否可用,所以要保证半数以上的zookeeper节点运行。
半数以上运行机制:
集群至少需要三台服务器,并且强烈建议使用奇数个服务器。因为zookeeper 通过判断大多数节点的存活来判断整个服务是否可用。比如3个节点,挂掉了2个表示整个集群挂掉,而用偶数4个,挂掉了2个也表示其并不是大部分存活,因此也会挂掉。
参考:https://www.cnblogs.com/ysocean/p/9860529.html
二、集群角色
zookeeper 集群中总共有三种角色,分别是leader(主节点)、follower(子节点)、 observer(次级子节点);
- leader:主节点,又名领导者。用于写入数据,通过选举产生,如果宕机将会选举新的主节点。
- follwer:子节点,又名追随者。用于实现数据的读取。同时他也是主节点的备选节点,并用拥有投票权。
- observer:次级子节点,又名观察者。用于读取数据,与follower区别在于没有投票权,不能选为主节点。并且在计算集群可用状态时不会将observer计算入内。
observer配置:只要在集群配置的配置文件中加上observer后缀即可,示例如下:
server.3=127.0.0.1:2889:3889:observer
三、zookeeper集群部署
因为机器资源有限,本次搭建zookeeper的伪集群。
1、简介
(1)Zookeeper集群的配置说明:
server.<节点ID>=<ip>:<数据同步端口>:<选举端口>
- 节点ID:服务id手动指定1至125之间的数字,并写到对应服务节点的 {dataDir}/myid 文件中。
- IP地址:节点的远程IP地址,可以相同。但生产环境就不能这么做了,因为在同一台机器就无法达到容错的目的。所以这种称作为伪集群。
- 数据同步端口:主从同时数据复制端口。
- 选举端口:主从节点选举端口。
(2)myid 文件
在搭建zookeeper集群的时候,zookeeper的节点ID是配置在 myid 文件中的;myid 文件需要放到配置文件配置的 dataDir 目录下面。
2、创建3个data目录用于存储各节点数据
mkdir -p /usr1/zookeeper/data/zoo1
mkdir -p /usr1/zookeeper/data/zoo2
mkdir -p /usr1/zookeeper/data/zoo3
3、编写myid文件
echo 1 > /usr1/zookeeper/data/zoo1/myid
echo 3 > /usr1/zookeeper/data/zoo2/myid
echo 2 > /usr1/zookeeper/data/zoo3/myid
4、zookeeper的配置文件
(1)节点1的配置文件:zoo1.cfg
tickTime=2000
dataDir=/usr1/zookeeper/data/zoo1
clientPort=2181
initLimit=5
syncLimit=2
#集群配置,必须配置在所有节点的zoo.cfg文件中
server.1=192.168.1.1:2887:3887
server.2=192.168.1.1:2888:3888
server.3=192.168.1.1:2889:3889
(2)节点2的配置文件:zoo2.cfg
tickTime=2000
dataDir=/usr1/zookeeper/data/zoo2
clientPort=2181
initLimit=5
syncLimit=2
#集群配置,必须配置在所有节点的zoo.cfg文件中
server.1=192.168.1.1:2887:3887
server.2=192.168.1.1:2888:3888
server.3=192.168.1.1:2889:3889
(3)节点3的配置文件:zoo3.cfg
tickTime=2000
dataDir=/usr1/zookeeper/data/zoo3
clientPort=2181
initLimit=5
syncLimit=2
#集群配置,必须配置在所有节点的zoo.cfg文件中
server.1=192.168.1.1:2887:3887
server.2=192.168.1.1:2888:3888
server.3=192.168.1.1:2889:3889
5、启动zookeeper服务
./bin/zkServer.sh start conf/zoo1.cfg
./bin/zkServer.sh start conf/zoo2.cfg
./bin/zkServer.sh start conf/zoo3.cfg
6、分别查看状态
./bin/zkServer.sh status conf/zoo1.cfg
Mode: follower
./bin/zkServer.sh status conf/zoo2.cfg
Mode: leader
./bin/zkServer.sh status conf/zoo3.cfg
Mode: follower
7、检查集群的数据同步
连接指定的节点:
./bin/zkCli.sh -server 127.0.0.1:2181
在任意一个节点创建数据,查看其他节点是否同步成功;
四、选举机制
1、查看节点的状态
./bin/zkServer.sh status <zoo配置文件>
./bin/zkServer.sh status conf/zoo1.cfg
Mode: follower
./bin/zkServer.sh status conf/zoo2.cfg
Mode: leader
./bin/zkServer.sh status conf/zoo3.cfg
Mode: follower
可以发现节点2为leader;
2、选举机制
Zookeeper默认采用了FastLeaderElection算法,且投票数大于半数则胜出的机制;
什么时候会触发选举呢?
- 服务节点初始化启动(全新集群选举);
- 半数以上的节点无法和 leader 建立连接;
2.1 全新集群选举
全新集群选举是新搭建起来的,没有数据ID和逻辑时钟数据影响集群的选举;
若进行Leader选举,则至少需要两台机器,这里选取3台机器组成的服务器集群为例。在集群初始化阶段,当有一台服务器Server1启动时,其单独无法进行和完成Leader选举,当第二台服务器Server2启动时,此时两台机器可以相互通信,每台机器都试图找到Leader,于是进入Leader选举过程。选举过程如下:
(1) 每个Server发出一个投票。由于是初始情况,Server1和Server2都会将自己作为Leader服务器来进行投票,每次投票会包含所推举的服务器的myid和ZXID,使用(myid, ZXID)来表示,此时Server1的投票为(1, 0),Server2的投票为(2, 0),然后各自将这个投票发给集群中其他机器。
(2) 接受来自各个服务器的投票。集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器。
(3) 处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK规则如下
· 优先检查ZXID。ZXID比较大的服务器优先作为Leader。
· 如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。
对于Server1而言,它的投票是(1, 0),接收Server2的投票为(2, 0),首先会比较两者的ZXID,均为0,再比较myid,此时Server2的myid最大,于是更新自己的投票为(2, 0),然后重新投票,对于Server2而言,其无须更新自己的投票,只是再次向集群中所有机器发出上一次投票信息即可。
(4) 统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于Server1、Server2而言,都统计出集群中已经有两台机器接受了(2, 0)的投票信息,此时便认为已经选出了Leader。
(5) 改变服务器状态。一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING。
2.2 非全新集群选举
对于正常运行的 Zookeeper 集群,一旦中途有服务器宕机(leader),则需要重新选举时,选举的时候就要引入服务器ID、数据ID(zxid)和逻辑时钟(投票次数,每一轮投票完成,投票次数都会增加)。
(1)首先统计逻辑时钟是否相同,逻辑时钟小,则说明途中存在宕机问题。因此该数据不完整,那么选举结果被忽略,重新投票选举;
(2)统一逻辑时钟之后,对比数据ID值,数据ID反映了数据的新旧程度,因此数据ID大的节点胜出;
(3)如果逻辑时钟和数据ID值都相同,那么就去比较服务器ID,服务器ID大的胜出;
简单的讲,非全新集群选举时是优中选优,保证 Leader 是 Zookeeper 集群中数据最完整、最可靠的一台服务器。
在集群运行其间如果有follower或observer节点宕机,只要不超过半数并不会影响整个集群服务的正常运行。但如果leader宕机,将暂停对外服务,所有follower将进入LOOKING 状态,进入选举流程。
3、数据同步机制
zookeeper 的数据同步是为了保证各节点中数据的一至性,同步时涉及两个流程,一个是正常的客户端数据提交,另一个是集群某个节点宕机在恢复后的数据同步。
3.1 客户端写入请求
写请求的处理是需要 leader 去处理的,若客户端请求的是 follower,则由 follower 将请求转发给 leader 进行同步处理;
(1)client向zk中的server发送写请求,如果该server不是leader,则会将该写请求转发给leader server,leader将请求事务以proposal形式分发给follower;
(2)当follower收到收到leader的proposal时,根据接收的先后顺序处理proposal;
(3)当Leader收到follower针对某个proposal过半的 ack后,则发起事务提交,重新发起一个commit的proposal;
(4)Follower收到commit的proposal后,记录事务提交,并把数据更新到内存数据库;
(5)当写成功后,反馈给client。
3.2 服务节点初始化同步
在集群运行过程当中如果有一个follower节点宕机,由于宕机节点没过半,集群仍然能正常服务。当leader 收到新的客户端请求,此时无法同步给宕机的节点,这就造成数据不一至。为了解决这个问题,当节点启动时,第一件事情就是找当前的Leader,比对数据是否一至,不一至则开始同步,同步完成之后在进行对外提供服务。
如何比对Leader的数据版本呢?通过ZXID事物ID来确认。比Leader的ZXID小就需要同步。
ZXID说明:
ZXID是一个长度64位的数字,其中低32位是按照数字递增,任何数据的变更都会导致,低32位的数字简单加1。高32位是leader周期编号,每当选举出一个新的leader时,新的leader就从本地事物日志中取出ZXID,然后解析出高32位的周期编号,进行加1,再将低32位的全部设置为0。这样就保证了每次新选举的leader后,保证了ZXID的唯一性而且是保证递增的。
4、四字运维命令
ZooKeeper响应少量命令。每个命令由四个字母组成。可通过telnet或nc向ZooKeeper发出命令。
这些命令默认是关闭的,需要配置 4lw.commands.whitelist 来打开,可打开部分或全部。
(1)打开四字因为命令,示例如下:
# 打开指定命令
4lw.commands.whitelist=stat, ruok, conf, isro
# 打开全部命令
4lw.commands.whitelist=*
(2)安装Netcat工具,使用nc命令:
#安装Netcat 工具
yum install -y nc
#查看服务器及客户端连接状态
echo stat | nc localhost 2181
(3)常用命令
echo stat|nc 127.0.0.1 2181 查看哪个节点被选择作为follower或者leader
使用echo ruok|nc 127.0.0.1 2181 测试是否启动了该Server,若回复imok表示已经启动。
echo dump| nc 127.0.0.1 2181 ,列出未经处理的会话和临时节点。
echo kill | nc 127.0.0.1 2181 ,关掉server
echo conf | nc 127.0.0.1 2181 ,输出相关服务配置的详细信息。
echo cons | nc 127.0.0.1 2181 ,列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。
echo envi |nc 127.0.0.1 2181 ,输出关于服务环境的详细信息(区别于 conf 命令)。
echo reqs | nc 127.0.0.1 2181 ,列出未经处理的请求。
echo wchs | nc 127.0.0.1 2181 ,列出服务器 watch 的详细信息。
echo wchc | nc 127.0.0.1 2181 ,通过 session 列出服务器 watch 的详细信息,它的输出是一个与 watch 相关的会话的列表。
echo wchp | nc 127.0.0.1 2181 ,通过路径列出服务器 watch 的详细信息。它输出一个与 session 相关的路径。
(4)命令列表
1. conf:3.3.0中的新增功能:打印有关服务配置的详细信息。
2. cons:3.3.0中的新增功能:列出了连接到该服务器的所有客户端的完整连接/会话详细信息。包括有关已接收/已发送的数据包数量,会话ID,操作等待时间,最后执行的操作等信息。
3. crst:3.3.0中的新增功能:重置所有连接的连接/会话统计信息。
4. dump:列出未完成的会话和临时节点。这仅适用于领导者。
5. envi:打印有关服务环境的详细信息
6. ruok:测试服务器是否以非错误状态运行。如果服务器正在运行,它将以imok响应。否则,它将完全不响应。响应“ imok”不一定表示服务器已加入仲裁,只是服务器进程处于活动状态并绑定到指定的客户端端口。使用“ stat”获取有关状态仲裁和客户端连接信息的详细信息。
7. srst:重置服务器统计信息。
8. srvr:3.3.0中的新功能:列出服务器的完整详细信息。
9. stat:列出服务器和连接的客户端的简要详细信息。
10. wchs:3.3.0中的新增功能:列出有关服务器监视的简要信息。
11. wchc:3.3.0中的新增功能:按会话列出有关服务器监视的详细信息。这将输出具有相关监视(路径)的会话(连接)列表。请注意,根据手表的数量,此操作可能会很昂贵(即影响服务器性能),请小心使用。
12. dirs:3.5.1中的新增功能:以字节为单位显示快照和日志文件的总大小
13. wchp:3.3.0中的新增功能:按路径列出有关服务器监视的详细信息。这将输出具有关联会话的路径(znode)列表。请注意,根据手表的数量,此操作可能会很昂贵(即影响服务器性能),请小心使用。
14. mntr:3.4.0中的新增功能:输出可用于监视集群运行状况的变量列表。
Zookeeper选举参考:https://www.cnblogs.com/leesf456/p/6107600.html