欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

注册不上zookeeper无报错_Zookeeper 跨区高可用方案

发布时间:2025/4/17 编程问答 79 豆豆
生活随笔 收集整理的这篇文章主要介绍了 注册不上zookeeper无报错_Zookeeper 跨区高可用方案 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

最近由于业务需求,测试各种组件的高可用性。由于我们的环境在AWS 北京部署。只有两个Aviable Zone(可用区)。

注释:有两个数据中心,相互需要做容灾的需求,和本文测试的情况是相同的。

而Zookeeper需要3个以上的单数节点同时工作,并且,必须保证半数以上的节点存活,还能正常提供服务。

那么,针对只有两个AZ的情况,不管怎么规划,都有概率遇到存在半数以上的AZ挂掉,导致整个Zookeeper不可用的情况。

所以,我们能做的就是,在这个AZ挂掉之后,我们怎么尽快处理,并恢复环境。

我们准备两个软件安装好,参数配置好的机器。在可用区1完全挂掉之后,可以手动启动两个备用节点。将可用区2的Zookeeper数量增加过半数。就可以在可用区2恢复Zookeeper的服务。

参考下图:

以上的设想,是否能实现呢?

那我们今天就来测试一下。

1. 一共准备了5台机器,作为测试

2. Zookeeper的下载与安装。

2.1 Zookeeper官方下载地址

2.2 下载软件

2.3 详细Zookeeper安装步骤,请参考:

2.4 zoo.cfg的配置

#cat zoo.cfgtickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zookeeper/data

dataLogDir=/data/zookeeper/log

clientPort=2181

autopurge.snapRetainCount=3

autopurge.purgeInterval=6

server.1=172.31.9.73:2888:3888

server.2=172.31.20.233:2888:3888

server.3=172.31.26.111:2888:3888

server.4=172.31.17.68:2888:3888

server.5=172.31.16.33:2888:3888

2.5  根据zoo.cfg创建data和log两个文件夹mkdir -p /data/zookeeper/data

mkdir -p /data/zookeeper/log

2.6 根据节点号码,修改文件echo 1 > /data/zookeeper/data/myid

3. 一共准备了5台EC2进行测试,并且都已经安装好Zookeeper

但是只启动三台,另两个机器作为standby

下图可以看到,已经有三台启动zookeeper,

注意,在Zookeeper启动的过程中,必须保证三台及以上,zookeeper集群才能正常工作

4. 接下来,我开始逐个机器关机,看zookeeper的状态

当前leader在zk3上,我们先关闭zk1,再关闭zk3,看Leader会不会飘到zk2上

4.1 在zk1上执行kill,杀掉进程[root@ip-172-31-9-73 ~]# jps

12438 Jps

7545 QuorumPeerMain

[root@ip-172-31-9-73 ~]# zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /root/zookeeper-3.4.14/bin/../conf/zoo.cfg

Mode: follower

[root@ip-172-31-9-73 ~]# kill -9 7545

4.2 在zk5上通过zkCli链接zk3,并可以查询数据。

在zk1上kill掉进程之后,理论上,还有zk2和zk3存活,但是zkCli的连接显示已经报错。[root@ip-172-31-16-33 bin]# ./zkCli.sh -server 172.31.26.111:2181

Connecting to 172.31.26.111:2181

......

[zk: 172.31.26.111:2181(CONNECTED) 0] ls /

[zk-permanent, zookeeper, test]

[zk: 172.31.26.111:2181(CONNECTED) 1] 2019-06-23 07:28:06,581 [myid:] - INFO  [main-SendThread(ip-172-31-26-111.cn-north-1.compute.internal:2181):ClientCnxn$SendThread@1158] - Unable to read additional data from server sessionid 0x30000c504530000, likely server has closed socket, closing socket connection and attempting reconnect

......

2019-06-23 07:28:09,822 [myid:] - INFO  [main-SendThread(ip-172-31-26-111.cn-north-1.compute.internal:2181):ClientCnxn$SendThread@1025] - Opening socket connection to server ip-172-31-26-111.cn-north-1.compute.internal/172.31.26.111:2181. Will not attempt to authenticate using SASL (unknown error)

2019-06-23 07:28:09,824 [myid:] - INFO  [main-SendThread(ip-172-31-26-111.cn-north-1.compute.internal:2181):ClientCnxn$SendThread@879] - Socket connection established to ip-172-31-26-111.cn-north-1.compute.internal/172.31.26.111:2181, initiating session

2019-06-23 07:28:09,825 [myid:] - INFO  [main-SendThread(ip-172-31-26-111.cn-north-1.compute.internal:2181):ClientCnxn$SendThread@1158] - Unable to read additional data from server sessionid 0x30000c504530000, likely server has closed socket, closing socket connection and attempting reconnect

4.3 我们继续 kill掉zk3上的进程,只保留zk2上的进程。但是我们已经无法确认zk2是Leader还是Follow,或者说,他是否还保留有数据。[root@ip-172-31-26-111 bin]# jps

4183 QuorumPeerMain

4648 Jps

[root@ip-172-31-26-111 bin]# kill -9 4183

[root@ip-172-31-26-111 bin]# jps

4658 Jps

4.4 zk3上进程kill掉之后,链接就不只是上面的报错了,而是直接连接拒绝[root@ip-172-31-16-33 bin]# ./zkCli.sh -server 172.31.26.111:2181

Connecting to 172.31.26.111:2181

......

Welcome to ZooKeeper!

2019-06-23 07:35:18,411 [myid:] - INFO  [main-SendThread(ip-172-31-26-111.cn-north-1.compute.internal:2181):ClientCnxn$SendThread@1025] - Opening socket connection to server ip-172-31-26-111.cn-north-1.compute.internal/172.31.26.111:2181. Will not attempt to authenticate using SASL (unknown error)

JLine support is enabled

2019-06-23 07:35:18,533 [myid:] - INFO  [main-SendThread(ip-172-31-26-111.cn-north-1.compute.internal:2181):ClientCnxn$SendThread@1162] - Socket error occurred: ip-172-31-26-111.cn-north-1.compute.internal/172.31.26.111:2181: Connection refused

[zk: 172.31.26.111:2181(CONNECTING) 0] 2019-06-23 07:35:19,639 [myid:] - INFO  [main-SendThread(ip-172-31-26-111.cn-north-1.compute.internal:2181):ClientCnxn$SendThread@1025] - Opening socket connection to server ip-172-31-26-111.cn-north-1.compute.internal/172.31.26.111:2181. Will not attempt to authenticate using SASL (unknown error)

2019-06-23 07:35:19,640 [myid:] - INFO  [main-SendThread(ip-172-31-26-111.cn-north-1.compute.internal:2181):ClientCnxn$SendThread@1162] - Socket error occurred: ip-172-31-26-111.cn-north-1.compute.internal/172.31.26.111:2181: Connection refused

4.5 可以看到zk2上的进程还在,# jps

5155 QuorumPeerMain

5211 Jps

4.6 并且通过下面命令,可以检查到zk2 的2181端口还在提供服务# echo ruok | nc localhost 2181

imok

4.7 但是其他命令是没有正常输出的,只有echo ruok | nc localhost 2181输出ok。# echo ruok | nc 172.31.16.33 2181

imok[root@ip-172-31-16-33 bin]# echo conf | nc 172.31.16.33 2181

This ZooKeeper instance is not currently serving requests

# echo dump | nc 172.31.16.33 2181

This ZooKeeper instance is not currently serving requests

4.8  ZooKeeper 四字命令ZooKeeper 四字命令功能描述

conf输出相关服务配置的详细信息。

cons列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。包括“接受 / 发送”的包数量、会话 id 、操作延迟、最后的操作执行等等信息。

dump列出未经处理的会话和临时节点。

envi输出关于服务环境的详细信息(区别于 conf 命令)。

reqs列出未经处理的请求

ruok测试服务是否处于正确状态。如果确实如此,那么服务返回“imok ”,否则不做任何相应。

stat输出关于性能和连接的客户端的列表。

wchs列出服务器 watch 的详细信息。

wchc通过 session 列出服务器 watch 的详细信息,它的输出是一个与watch 相关的会话的列表。

wchp通过路径列出服务器watch 的详细信息。它输出一个与 session相关的路径。

4.9 正常情况下,以上命令可以输出:

# echo dump | nc 172.31.20.233 2181SessionTracker dump:

org.apache.zookeeper.server.quorum.LearnerSessionTracker@77714302

ephemeral nodes dump:

Sessions with Ephemerals (0):

# echo conf | nc 172.31.20.233 2181clientPort=2181

dataDir=/data/zookeeper/data/version-2

dataLogDir=/data/zookeeper/log/version-2

tickTime=2000

maxClientCnxns=60

minSessionTimeout=4000

maxSessionTimeout=40000

serverId=2

initLimit=10

syncLimit=5

electionAlg=3

electionPort=3888

quorumPort=2888

peerType=0

# echo envi| nc 172.31.20.233 2181Environment:

zookeeper.version=3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf, built on 03/06/2019 16:18 GMT

host.name=ip-172-31-20-233.cn-north-1.compute.internal

java.version=1.8.0_212

java.vendor=Oracle Corporation

java.home=/usr/java/jdk1.8.0_212-amd64/jre

java.class.path=/root/zookeeper-3.4.14/bin/../zookeeper-server/target/classes:/root/zookeeper-3.4.14/bin/../build/classes:/root/zookeeper-3.4.14/bin/../zookeeper-server/target/lib/*.jar:/root/zookeeper-3.4.14/bin/../build/lib/*.jar:/root/zookeeper-3.4.14/bin/../lib/slf4j-log4j12-1.7.25.jar:/root/zookeeper-3.4.14/bin/../lib/slf4j-api-1.7.25.jar:/root/zookeeper-3.4.14/bin/../lib/netty-3.10.6.Final.jar:/root/zookeeper-3.4.14/bin/../lib/log4j-1.2.17.jar:/root/zookeeper-3.4.14/bin/../lib/jline-0.9.94.jar:/root/zookeeper-3.4.14/bin/../lib/audience-annotations-0.5.0.jar:/root/zookeeper-3.4.14/bin/../zookeeper-3.4.14.jar:/root/zookeeper-3.4.14/bin/../zookeeper-server/src/main/resources/lib/*.jar:/root/zookeeper-3.4.14/bin/../conf:

java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib

java.io.tmpdir=/tmp

java.compiler=

os.name=Linux

os.arch=amd64

os.version=4.14.123-86.109.amzn1.x86_64

user.name=root

user.home=/root

user.dir=/root/zookeeper-3.4.14/bin

5. 这个时候,我去启动另外两个备用节点,zk4,zk5.这个两个节点都是第一次启动。

6. 再次连接到zookeeper上,可以看到,至少数据还是没有丢失的[root@ip-172-31-16-33 bin]# ./zkCli.sh -server 172.31.16.33:2181

Connecting to 172.31.16.33:2181

......

[zk: 172.31.16.33:2181(CONNECTED) 0] ls /

[zk-permanent, zookeeper, test]

7. 通过以上测试,似乎是达到我们预期的结果。唯一的一点小问题,就是:我们有3个节点,为什么关闭1个,剩余两个,就不能正常运行了呢?

其实,这里是有个“想当然”的小问题。

我们以为,只启动三个. 其实,Zookeeper集群,识别的是5个, 为什么呢?

Zookeeper靠什么去识别集群中有几个节点呢?当然不是靠“想当然”。一定是有配置文件告诉它。Zookeeper,只有两个配置文件zoo.cfg和myid。

那就只有zoo.cfg会影响到它了。

8. 我将zoo.cfg做如下修改之后。只开启3个节点,在关闭一个节点之后,还是可以正常运行的。

注释掉server2和server5# cat zoo.cfg

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zookeeper/data

dataLogDir=/data/zookeeper/log

clientPort=2181

autopurge.snapRetainCount=3

autopurge.purgeInterval=6

server.1=172.31.9.73:2888:3888

#server.2=172.31.20.233:2888:3888

server.3=172.31.26.111:2888:3888

server.4=172.31.17.68:2888:3888

#server.5=172.31.16.33:2888:3888

9. 关闭server4之后,还有server2和server3活着。[root@ip-172-31-26-111 ~]# zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /root/zookeeper-3.4.14/bin/../conf/zoo.cfg

Mode: leader

[root@ip-172-31-9-73 ~]# zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /root/zookeeper-3.4.14/bin/../conf/zoo.cfg

Mode: follower

10. 总结,如果考虑两个AZ的情况下,zookeeper节点数多的AZ出现灾难情况,我们如何快速恢复?

(假设Server1/Server2在1AZ,Server3/Server4/Server5在2AZ)

10.1. 在Zookeeper节点少的AZ,多准备2台配置好zookeeper的EC2,并关机待使用。Server4/Server5具体zoo.cfg配置如下tickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zookeeper/data

dataLogDir=/data/zookeeper/log

clientPort=2181

autopurge.snapRetainCount=3

autopurge.purgeInterval=6

server.3=172.31.26.111:2888:3888

server.4=172.31.17.68:2888:3888

server.5=172.31.16.33:2888:3888

10.2.  Server1/Server2/Server3,是正常运行的节点,配置如下:tickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zookeeper/data

dataLogDir=/data/zookeeper/log

clientPort=2181

autopurge.snapRetainCount=3

autopurge.purgeInterval=6

server.1=172.31.9.73:2888:3888

server.2=172.31.20.233:2888:3888

server.3=172.31.26.111:2888:3888

10.3.  灾难发生,Server1/Server2所在的1AZ挂掉的情况下,需要人工介入,将Server3的配置更改为如下配置,并重启Server3的zookeeper服务,然后启动Server4/Server5,一定要先启动Server3,注意顺序。tickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zookeeper/data

dataLogDir=/data/zookeeper/log

clientPort=2181

autopurge.snapRetainCount=3

autopurge.purgeInterval=6

server.3=172.31.26.111:2888:3888

server.4=172.31.17.68:2888:3888

server.5=172.31.16.33:2888:3888

10.4 日常运行状态

10.5 检查已经创建的znode信息./zkCli.sh -server 172.31.16.33:2181 ls /

Connecting to 172.31.16.33:2181

[zk-permanent, zookeeper, test]

10.6 关闭Server1/Server2,注意顺序,先关闭follow,如果先关闭leader,会发生切换。我们期望的是Server3最后以follow的身份存活。

11. 最终可以看到测试结果,一切都是按照我们“想当然”的方向发展。

12. 最后验证zookeeper中的znode数据,还是都存在的。./zkCli.sh  -server 172.31.16.33:2181 ls /

Connecting to 172.31.16.33:2181

[zk-permanent, zookeeper, test]

13. 其实数据一直是在这个路径下,只要有一个节点还保留,就会保存下去。# ls /data/zookeeper/data/

myid  version-2  zookeeper_server.pid

注意:一定要保证Server4/Server5的下面两个路径是空的,不然会出现,Server4/Server5识别的是之前的陈旧信息。/data/zookeeper/data/version-2

/data/zookeeper/log/version-2

14. 说到这里,我们可以理解到,Zookeeper的全部数据,都是存放在下面两个路径中。如果需要做备份,可以直接在OS层面,做cp备份即可。dataDir=/data/zookeeper/data

dataLogDir=/data/zookeeper/log

衍生一个想法,就是如果想做跨Region,北京(主环境)到宁夏(容灾环境)的zookeeper的高可用怎么做呢?

我们可以考虑将北京的zookeeper的数据文件定期备份,并导入到宁夏的环境。

具体步骤:

<1. 在宁夏启动一个Zookeeper集群,并配置好,然后关闭zookeeper服务,清空掉数据文件夹。

<2. 在北京,通过脚本定期检查zookeeper各个节点状态,从一个运行健康的节点,定期备份数据到S3的一个bucket,为每个文件加上时间戳。

<4. 然后在宁夏,从S3读取备份文件,并还原到灾备的zookeeper中。

总结

以上是生活随笔为你收集整理的注册不上zookeeper无报错_Zookeeper 跨区高可用方案的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。