推荐阅读
Helm3(K8S 资源对象管理工具)视频教程:https://edu.csdn.net/course/detail/32506
Helm3(K8S 资源对象管理工具)博客专栏:https://blog.csdn.net/xzk9381/category_10895812.html
本文原文链接:https://blog.csdn.net/xzk9381/article/details/120332702,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。
Zookeeper 集群节点热扩容和迁移
公司内的一套 3 节点的 Zookeeper 集群需要更换节点(使用域名访问),为了保证节点迁移过程中服务可以正常响应,决定使用节点扩容和下线旧节点的方式来实现迁移。
很多文章里写的是先拷贝数据,再启动节点。我觉得如果数据量小的话可以直接扩容然后等待同步完成。如果数据量很大,那么也可以考虑使用某些开源工具(例如 zkcopy 来)来同步数据。这里就不做演示了。
首先我们当前的集群环境是三个节点,信息如下:
IP 地址 | myid |
---|---|
192.168.10.1 | 101 |
192.168.10.2 | 102 |
192.168.10.3 | 103 |
现在需要将这个集群中迁移到如下节点中:
- 192.168.11.1
- 192.168.11.2
- 192.168.11.3
在迁移之前,我们首先来熟悉一下 zookeeper 的相关知识。
一、zookeeper 集群原理
ZooKeeper 是一个开源的分布式协调服务,由雅虎创建,是 Google Chubby 的开源实现。 分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协 调/通知、集群管理、Master 选举、分布式锁和分布式队列 等功能。
1. 集群角色
zookeeper 集群中分位三种角色:
- Leader (领导)
- Follower (追随者)
- Observer (观察员)
一个 ZooKeeper 集群同一时刻只会有一个 Leader,其他都是 Follower 或 Observer。ZooKeeper 配置很简单,每个节点的配置文件 zoo.cfg 都是一样的,只有 data 目录下的 myid 文件中的值不一样。myid 的值必须与 zoo.cfg 中 server.<数值> 的 <数值> 部分保持一致。
2. 节点读写
ZooKeeper 集群的所有机器通过一个 Leader 选举过程来选定一台被称为 Leader 的机器,Leader 服务器为客户端提供读和写服务。
Follower 和 Observer 都能提供读服务,不能提供写服务。两者唯一的区别在于 Observer 机器不参与 Leader 选举过程,也不参与写操作的"过半写成功"策略,因此 Observer 可以在不影响写性能的情况下提升集群的读性能。
3. session 说明
Session 是指客户端会话,在 ZooKeeper 中,一个客户端连接是指客户端和 ZooKeeper 服务器之间的TCP长连接。
ZooKeeper 对外的服务端口默认是 2181。客户端启动时,首先会与服务器建立一个TCP 连接,从第一次连接建立开始,客户端会话的生命周期也就开始了,通过这个连接,客户端能够通过心跳检测和服务器保持有效的会话,也能够向 ZooKeeper 服务器发送请求并接受响应,同时还能通过该连接接收来自服务器的 Watch 事件通知。
Session 的 SessionTimeout 值用来设置一个客户端会话的超时时间。当服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在 SessionTimeout 规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。
4. zookeeper 选举
zookeeper 的选举过程分为两个阶段:
- 数据恢复阶段:每台服务器在启动前,都会从本地目录找自己所拥有的 Zxid(最大事务id),每一次对 Zookeeper 的操作都是一个事务,每次事务都会递增事务 id,事务 id 越大,则事务越新。
- 选举阶段:zookeeper 集群开始选举时,每个节点都会提交一个选举协议,协议中包括如下内容:
- 当前节点的 Zxid
- 选举 id(myid 文件中的值)
- 逻辑时钟值(和选举轮数有关),作用是确保每台 zk 服务器处于同一轮选举中
- 状态(Looking):选举状态,包括 Leader,Follower,Observer
在选举过程中,会遵循如下原则:
- 首先比较 Zxid,哪个节点的 Zxid 最大就选择谁作为 leader
- 在所有节点的 Zxid 全都一致的情况下,则比较选举 id,选举 id 较大的节点会作为 leader
- 注意 Zookeeper 集群节点最好为奇数个,集群有一个过半存活集群,超过半数才可以选举成功。根据paxos理论,只有集群中超过半数的节点存活才能保证集群的一致性。假如目前集群有5个节点,我们最多允许2个节点不可用,因为3>5\2。当集群扩容到6个节点的时候,我们仍然只能最多允许2个节点不可用,到3个节点不可用时,将不满足paxos理论,因为3>6\2不成立。也就是说当集群节点数n为偶数时,其可用性与n-1是一样的。
- 由于zookeeper只允许 myid 大的节点连接到 myid 小的节点,所以启动 zookeeper 的顺序应该按照 myid 从小到大启动,最后再启动leader节点。
接下来详细说一下 Zookeeper 的选举过程,只有清楚地了解该过程,才能制定合理的迁移步骤。zookeeper 默认使用快速选举(FastLeaderElection),在此重点了解快速选举:
- 每个节点向集群中的其他 zookeeper 建立连接,并且只有 myid 比对方大的连接才会被接受(也就是每2台只会有1个连接,避免连接浪费)
- 每台 zookeeper 默认先投自己,然后向集群广播自己的选票
- 收到对方的选票时,依次比较 epoch(选举轮数)、Zxid(事务id)、myid,较大者胜出,更新选票并广播
- 如果收到的选票中有某个节点超过集群半数,则胜出当选为leader,其他节点为follower
Zookeeper 在选举成功后,首先会同步数据,这样可以确保集群节点数据一致性,确保客户端无论从哪个zk服务器获取数据都是一致的,并且在 leader 挂掉后,follower 节点可以顺利接管任务。这种实现数据一致性的过程称为原子广播(Atomic Brodcast)。
本文原文链接:https://blog.csdn.net/xzk9381/article/details/120332702,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。
二、节点扩容过程说明
1. 查看当前集群的 leader
首先看一下当前 zookeeper 集群的配置(其他配置已忽略,所有节点保持一致即可):
server.101=192.168.10.1:2888:3888
server.102=192.168.10.2:2888:3888
server.103=192.168.10.3:2888:3888
可以使用 Zookeeper 提供的四字命令来快速查看集群中哪个节点是 leader 或 follower:
echo mntr | nc localhost 2181
返回结果如下(可以在 zk_server_state 中查看当前节点的角色):
[@localhost ~]# echo mntr | nc localhost 2181
zk_version 3.4.6-1569965, built on 02/20/2014 09:09 GMT
zk_avg_latency 0
zk_max_latency 5
zk_min_latency 0
zk_packets_received 30
zk_packets_sent 29
zk_num_alive_connections 4
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count 1739
zk_watch_count 28
zk_ephemerals_count 99
zk_approximate_data_size 893067
zk_open_file_descriptor_count 37
zk_max_file_descriptor_count 265535
zk_followers 2
zk_synced_followers 2
zk_pending_syncs 0
通过使用命令查看角色状态,我们假设当前的 leader 是 192.168.10.2 节点(不要觉得这个假设不合理,因为实际过程中就是这样一个结果,大家可以仔细回想一下选举过程就能明白了,或者把下面的内容读完,也会明白原因)。
接下来就是将新的节点扩到集群中。
2. 扩容节点 192.168.11.1
首先需要将 192.168.11.1 节点扩到集群中,步骤如下:
- 在 data 目录下创建 myid 文件,内容为 111
注意一点,新扩容的节点 myid 值一定要大于集群中原有节点的 myid 值,这样新增的节点在后续更新中才会被选为 leader
- 编辑 zoo.cfg 文件,内容如下:
server.101=192.168.10.1:2888:3888
server.102=192.168.10.2:2888:3888
server.103=192.168.10.3:2888:3888
server.111=192.168.11.1:2888:3888
注意不要急于在配置文件把所有新节点的地址都加上
- 配置修改完成后,重启 zookeeper:
./zkServer.sh restart
- 重启成功后使用四字命令查看当前节点和 leader(此时还是 192.168.10.2 节点) 节点的状态:
echo mntr | nc localhost 2181
- 如果可以查看到当前节点的角色为 follower ,并且 leader 节点中显示 zk_followers 的值为 3,则代表节点扩容成功:
[@localhost ~]# echo mntr | nc localhost 2181 | grep zk_followers
zk_followers 3
如果查看的集群信息不正常,例如 leader 数量不对或者 follower 数量不对,或者集群没有响应,那么就需要还原整个集群。
3. 扩容节点 192.168.11.2
将 192.168.11.2 节点扩到集群中,步骤如下:
- 在 data 目录下创建 myid 文件,内容为 112
注意一点,新扩容的节点 myid 值一定要大于集群中原有节点的 myid 值,这样新增的节点在后续更新中才会被选为 leader
- 编辑 zoo.cfg 文件,内容如下:
server.101=192.168.10.1:2888:3888
server.102=192.168.10.2:2888:3888
server.103=192.168.10.3:2888:3888
server.111=192.168.11.1:2888:3888
server.112=192.168.11.2:2888:3888
注意不要急于在配置文件把所有新节点的地址都加上
- 配置修改完成后,重启 zookeeper:
./zkServer.sh restart
- 重启成功后使用四字命令查看当前节点和 leader(此时还是 192.168.10.2 节点) 节点的状态:
echo mntr | nc localhost 2181
- 如果可以查看到当前节点的角色为 follower ,并且 leader 节点中显示 zk_followers 的值为 4,则代表节点扩容成功:
[@localhost ~]# echo mntr | nc localhost 2181 | grep zk_followers
zk_followers 4
如果查看的集群信息不正常,例如 leader 数量不对或者 follower 数量不对,或者集群没有响应,那么就需要还原整个集群。
4. 扩容节点 192.168.11.3
将 192.168.11.3 节点扩到集群中,步骤如下:
- 在 data 目录下创建 myid 文件,内容为 113
注意一点,新扩容的节点 myid 值一定要大于集群中原有节点的 myid 值,这样新增的节点在后续更新中才会被选为 leader
- 编辑 zoo.cfg 文件,内容如下:
server.101=192.168.10.1:2888:3888
server.102=192.168.10.2:2888:3888
server.103=192.168.10.3:2888:3888
server.111=192.168.11.1:2888:3888
server.112=192.168.11.2:2888:3888
server.113=192.168.11.3:2888:3888
- 配置修改完成后,重启 zookeeper:
./zkServer.sh restart
- 重启成功后使用四字命令查看当前节点和 leader(此时还是 192.168.10.2 节点) 节点的状态:
echo mntr | nc localhost 2181
- 如果可以查看到当前节点的角色为 follower ,并且 leader 节点中显示 zk_followers 的值为 5,则代表节点扩容成功:
[@localhost ~]# echo mntr | nc localhost 2181 | grep zk_followers
zk_followers 5
如果查看的集群信息不正常,例如 leader 数量不对或者 follower 数量不对,或者集群没有响应,那么就需要还原整个集群。
5. 修改新节点 192.168.11.1 和 192.168.11.2 配置文件
在前面扩容 192.168.11.1 和 192.168.11.2 节点时,配置文件中写的节点信息不完整,所以在全部扩容完成后,需要将这两个节点的配置信息补充完整,最后的配置文件内容如下:
server.101=192.168.10.1:2888:3888
server.102=192.168.10.2:2888:3888
server.103=192.168.10.3:2888:3888
server.111=192.168.11.1:2888:3888
server.112=192.168.11.2:2888:3888
server.113=192.168.11.3:2888:3888
更新完成后重启 192.168.11.1 和 192.168.11.2 节点,并查看集群状态。
6. 修改旧节点配置文件
到目前为止,所有新增的节点配置文件已经保持一致,但是旧节点配置文件中还没有包含新增 3 个节点的信息,所以需要更新一下。需要注意的是,前面我们说到了,重启 zookeeper 集群时要先重启 follower 节点,最后重启 leader,所以首先将 192.168.10.1 和 192.168.10.3 节点的配置文件修改为如下:
server.101=192.168.10.1:2888:3888
server.102=192.168.10.2:2888:3888
server.103=192.168.10.3:2888:3888
server.111=192.168.11.1:2888:3888
server.112=192.168.11.2:2888:3888
server.113=192.168.11.3:2888:3888
修改完成后依次重启这两个节点。重启完成后查看集群状态。
如果集群状态正常则开始修改 192.168.10.2 节点的配置文件并重启。该节点重启完成后,如果没有读写 zookeeper 集群的操作,那么集群的 leader 则会变为节点 192.168.11.3,因为这个节点的 myid 是最大的。
本文原文链接:https://blog.csdn.net/xzk9381/article/details/120332702,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。
三、节点迁移过程说明
上面已经将新的节点扩容到集群中,为了实现我们服务迁移的目的,此时就需要修改原有的域名解析记录,将域名指向新增的三个节点上。修改域名解析后,需要将相关业务进行重启,这样可以避免由于缓存导致的 zookeeper 连接地址不正确。
待所有业务重启完成后,可以开始将集群中旧节点依次下线,步骤如下。
注意旧节点是依次下线,不能同时下线,否则在停止第三个节点时会导致集群判定没有超过半数节点存活而导致一场。
1. 下线 192.168.10.1 节点
首先关闭 192.168.10.1 节点上的 zookeeper 服务:
./zkServer.sh stop
依次修改其他五个节点中的配置文件,去掉 192.168.10.1 节点的信息,修改后的配置文件内容如下:
server.102=192.168.10.2:2888:3888
server.103=192.168.10.3:2888:3888
server.111=192.168.11.1:2888:3888
server.112=192.168.11.2:2888:3888
server.113=192.168.11.3:2888:3888
修改完成后依次重启这 5 个节点,并检查集群服务状态。如果集群当中没有读写操作,那么在所有的节点重启完成后,192.168.11.2 节点会成为新的 leader,因为在重启 192.168.11.3 时,集群重新选举,此时 192.168.11.2 的 myid 最大。
2. 下线 192.168.10.2 节点
首先关闭 192.168.10.2 节点上的 zookeeper 服务:
./zkServer.sh stop
依次修改其他五个节点中的配置文件,去掉 192.168.10.2 节点的信息,修改后的配置文件内容如下:
server.103=192.168.10.3:2888:3888
server.111=192.168.11.1:2888:3888
server.112=192.168.11.2:2888:3888
server.113=192.168.11.3:2888:3888
修改完成后依次重启这 4 个节点,并检查集群服务状态。如果集群当中没有读写操作,那么在所有的节点重启完成后,192.168.11.3 节点会成为新的 leader,因为在重启 192.168.11.2 时,集群重新选举,此时 192.168.11.3 的 myid 最大。
3. 下线 192.168.10.3 节点
首先关闭 192.168.10.3 节点上的 zookeeper 服务:
./zkServer.sh stop
依次修改其他五个节点中的配置文件,去掉 192.168.10.3 节点的信息,修改后的配置文件内容如下:
server.111=192.168.11.1:2888:3888
server.112=192.168.11.2:2888:3888
server.113=192.168.11.3:2888:3888
修改完成后依次重启这 3 个节点,并检查集群服务状态。如果集群当中没有读写操作,那么在所有的节点重启完成后,192.168.11.2 节点会成为新的 leader,因为在重启 192.168.11.3 时,集群重新选举,此时 192.168.11.2 的 myid 最大。
四、总结
到目前为止,整个集群的迁移就已经完成了,操作的过程会比较多,并且在这个过程中 leader 节点会多次变更。只要实践一次,就可以加深对 zookeeper 选举机制的理解。
本文原文链接:https://blog.csdn.net/xzk9381/article/details/120332702,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。
本文在编写过程中参考了博客:https://blog.csdn.net/jiabeis/article/details/100542405