4.1 集群选举机制
4.1.1 第一次启动
这里假设有5台服务器。
其实我们稍微总结一下,原来第一次选举就是选举myid 在中位的那台服务器啊,果然大佬都是站在c位的。但是这是有条件的,条件就是我们按照myid的顺序来启动服务器,如果不是那这个规律就不成立,只能够总结成为超过半数人参与选举的情况下,出身最好(myid最大)的当老大。这里如果觉得有疑问,可以自己按照上面讲的过程推算一下。
客户端可以给zookeeper服务集群进行写操作,每一次写操作都可以看作一次事务,这里有几个概念后续可能用到,简单介绍如下。
SID很好懂,zxid就是事务ID,客户端的每一次发送事务请求都会提交一个版本号,这个数值越大,说明服务器的版本越新。
这里Epoch可能会比较难懂,服务器每次参加一次选举Epoch就会+1,这就像是一个朝代中元老们的资历,而当选leader的一定是他们中Epoch最大的那个,因此它也可以说是一个Leader任期的代号,后续将结合案例具体介绍。
4.1.2 非第一次启动
您可以先大概看下下面的图片,看不懂没关系,我将拆解进行介绍。
首先我们思考一个问题,为什么要选举出leader呢?
如果只有一台服务器,我们完全可以自己做主,客户端发送的写操作我们进行响应,更新数据即可。但是现在是服务集群,可能有多台客户端向不同的服务器发送写的操作请求,这就需要考虑数据一致性的问题了。前面其实我们其实也提到过,对于写操作我们只让leader来做,对于读操作我们则可以让任一服务器进行响应,从而保证数据安全又能够分散服务器的压力。
再思考一个问题,什么情况会进行选举呢?
服务器初始化启动时。开国大典成立当然要选择老大了。我们在前一个小节介绍了这种情况。
某服务器运行期间无法与Leader保持连接时。这个比较难理解,其实我们可以打个比方,就跟古代一样,通信不发达,地方诸侯都靠信使获得与中央的通信,当有一天收不到中央的消息了,就会想皇帝是不是驾崩了,那我要选新皇帝啊,就会自己悄咪咪的联系其它诸侯王,问问圣上还安康否?如果那啥了我想投谁一票。当然,这个时候存在两个情况,一种皇帝真的驾崩了,一种是信使他遭遇了什么不测,也就是我们follower自己与leader断连了。如果第一种情况,就会开始重新选举,如果是第二种情况,其它诸侯王就会告诉它,皇帝还好好的呢,你小子快点找个新的信使跟他保持联系。Follower会与leader重连。
有新的服务器节点加入。新人来了不得打一架看看谁做老大吗?
第三种情况暂且不考虑,看看第二种情况。万一leader挂了,我们要怎么进行选举呢?
这是一个看资历的王国,皇帝驾崩了诸侯王们先回把epoch都增加1,也就是资历加1,看看谁在王朝中呆的时间久,也就是哪台服务器1的Epoch大,大的直接当leader。并且把这个epoch宣布为自己的任期代号(每次选举都是递增的,因此也是独一无二的)。
如果有多个诸侯王的epoch相同,就比比谁的zxid大,zxid是事务id,也就是哪台服务器的数据最新,大的胜出,毕竟它获得了最新的事务id,能力最强。
如果事务id是相同的,就看看谁的服务器id即sid最大。我们知道sid就是myid,是一开始就被写好了的,这就是纯纯的比出身了,看看谁是先皇长子。
怎么样,再结合图片内容,你学废了吗?
4.2 zookeeper启动停止脚本
4.2.1 脚本编写
我们前面都是每一台服务器分别进行启动与停止操作的,但是一台台服务器这么操作未免有些太麻烦了,不如写个脚本,就像之前分发文件一样,一次性的把各个服务器启动/停止完毕好了。
在~/bin目录下创建并编辑zk.sh.
#!/bin/bash case $1 in "start"){ for i in zookeeper01 zookeeper02 zookeeper03 do echo -------------- $i 启动 ---------------- ssh $i "~/Downloads/zookeeper-3.5.7/bin/zkServer.sh start" done } ;; "stop") { for i in zookeeper01 zookeeper02 zookeeper03 do echo -------------- $i 停止 ---------------- ssh $i "~/Downloads/zookeeper-3.5.7/bin/zkServer.sh stop" done } ;; "status") { for i in zookeeper01 zookeeper02 zookeeper03 do echo -------------- $i 状态 ---------------- ssh $i "~/Downloads/zookeeper-3.5.7/bin/zkServer.sh status" done } ;; esac
赋予执行权限。这样所有用户都可以对它为所欲为了。
chmod 777 zk.sh 1
如果您对于权限问题不熟悉,可以参考博客chmod 777 到底是啥 ???看完这个你就完全懂了!_人间世庄子的博客-CSDN博客_chmod777。
4.2.2 脚本测试
先测试一下状态。
[wangzhou@zookeeper01 bin]$ ./zk.sh status -------------- zookeeper01 状态 ---------------- wangzhou@zookeeper01's password: ZooKeeper JMX enabled by default Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: follower -------------- zookeeper02 状态 ---------------- wangzhou@zookeeper02's password: ZooKeeper JMX enabled by default Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: follower -------------- zookeeper03 状态 ---------------- wangzhou@zookeeper03's password: ZooKeeper JMX enabled by default Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: leader
没啥大毛病,不过它居然让我一一去输入密码,其实之前在分发文件时就存在这个问题,这是想要累死爷吗?我们解决下这个问题吧。参考博客SSH 三步解决免密登录_jeikerxiao的博客-CSDN博客_ssh免密登录配置ssh免密登录即可,这可太舒适了。
接下来测试关闭。
[wangzhou@zookeeper01 bin]$ ./zkServer.sh stop ZooKeeper JMX enabled by default Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg Stopping zookeeper ... no zookeeper to stop (could not find file /home/wangzhou/Downloads/zookeeper-3.5.7/zkData/zookeeper_server.pid)
似乎没有关掉
[wangzhou@zookeeper01 bin]$ ~/bin/zk.sh status -------------- zookeeper01 状态 ---------------- ZooKeeper JMX enabled by default Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: follower -------------- zookeeper02 状态 ---------------- ZooKeeper JMX enabled by default Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: follower -------------- zookeeper03 状态 ---------------- ZooKeeper JMX enabled by default Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: leader