zookeeper入门到精通04——zookeeper集群选举与集群操作

2022-10-26 17:55:11 浏览数 (2)

4.zookeeper集群选举与集群操作
  • 4.1 集群选举机制
    • 4.1.1 第一次启动
    • 4.1.2 非第一次启动
  • 4.2 zookeeper启动停止脚本
    • 4.2.1 脚本编写
    • 4.2.2 脚本测试

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.

代码语言:javascript复制
#!/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

赋予执行权限。这样所有用户都可以对它为所欲为了。

代码语言:javascript复制
chmod 777 zk.sh

如果您对于权限问题不熟悉,可以参考博客chmod 777 到底是啥 ???看完这个你就完全懂了!_人间世庄子的博客-CSDN博客_chmod777。

4.2.2 脚本测试

先测试一下状态。

代码语言:javascript复制
[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免密登录即可,这可太舒适了。

接下来测试关闭。

代码语言:javascript复制
[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)

似乎没有关掉

代码语言:javascript复制
[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

好惨啊,为啥呢?单独关也不能关,排除了脚本的命令写错了这个问题。

代码语言:javascript复制
[wangzhou@zookeeper01 zookeeper-3.5.7]$ ./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)

看看log。没发现啥异常。把log删除了,重新连接,再查看log。

代码语言:javascript复制
2022-04-04 12:32:57,246 [myid:] - INFO  [main:QuorumPeerConfig@135] - Reading configuration from: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg
2022-04-04 12:32:57,252 [myid:] - INFO  [main:QuorumPeerConfig@387] - clientPortAddress is 0.0.0.0:2181
2022-04-04 12:32:57,252 [myid:] - INFO  [main:QuorumPeerConfig@391] - secureClientPort is not set
2022-04-04 12:32:57,259 [myid:1] - INFO  [main:DatadirCleanupManager@78] - autopurge.snapRetainCount set to 3
2022-04-04 12:32:57,260 [myid:1] - INFO  [main:DatadirCleanupManager@79] - autopurge.purgeInterval set to 0
2022-04-04 12:32:57,260 [myid:1] - INFO  [main:DatadirCleanupManager@101] - Purge task is not scheduled.
2022-04-04 12:32:57,260 [myid:1] - INFO  [main:ManagedUtil@46] - Log4j found with jmx enabled.
2022-04-04 12:32:57,269 [myid:1] - INFO  [main:QuorumPeerMain@141] - Starting quorum peer
2022-04-04 12:32:57,276 [myid:1] - INFO  [main:ServerCnxnFactory@135] - Using org.apache.zookeeper.server.NIOServerCnxnFactory as server connection factory
2022-04-04 12:32:57,278 [myid:1] - INFO  [main:NIOServerCnxnFactory@673] - Configuring NIO connection handler with 10s sessionless connection timeout, 1 selector thread(s), 2 worker threads, and 64 kB direct buffers.
2022-04-04 12:32:57,282 [myid:1] - INFO  [main:NIOServerCnxnFactory@686] - binding to port 0.0.0.0/0.0.0.0:2181
2022-04-04 12:32:57,282 [myid:1] - ERROR [main:QuorumPeerMain@101] - Unexpected exception, exiting abnormally
java.net.BindException: Address already in use
        at sun.nio.ch.Net.bind0(Native Method)
        at sun.nio.ch.Net.bind(Net.java:433)
        at sun.nio.ch.Net.bind(Net.java:425)
        at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
        at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
        at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:67)
        at org.apache.zookeeper.server.NIOServerCnxnFactory.configure(NIOServerCnxnFactory.java:687)
        at org.apache.zookeeper.server.quorum.QuorumPeerMain.runFromConfig(QuorumPeerMain.java:148)
        at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:123)
        at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:82)
~                                                                                           

好家伙,原来端口被占用了,谁占用了?jps看不到呀,切换到root账号,jps发现原来这个服务在root账户上跑着呢。kill停掉,再来到用户目录启动,果然启动不了。

代码语言:javascript复制
[wangzhou@zookeeper01 bin]$ ./zkServer.sh start 
ZooKeeper JMX enabled by default
Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... ./zkServer.sh: line 158: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../logs/zookeeper-wangzhou-server-zookeeper01.out: Permission denied
FAILED TO START

原因是我们把zookeeper放在普通用户的home/xxx下了,这个目录的权限默认是755。我们之前启动是用的sudo,让它跑在了root上。基础不牢,地动山摇,看来linux的基础也是不可以被忽视的。

好的,那么想办法解决下吧。我们zookeeper的权限放开吧。

代码语言:javascript复制
[wangzhou@zookeeper03 Downloads]$ sudo chmod  777 -R zookeeper-3.5.7

测试下。

代码语言:javascript复制
[wangzhou@zookeeper03 Downloads]$ zookeeper-3.5.7/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

最后集群测试下。

代码语言:javascript复制
[wangzhou@zookeeper01 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.
Error contacting service. It is probably not running.
-------------- 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.
Error contacting service. It is probably not running.
-------------- 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.
Error contacting service. It is probably not running.
[wangzhou@zookeeper01 bin]$ ./zk.sh start
-------------- zookeeper01 启动 ----------------
ZooKeeper JMX enabled by default
Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
-------------- zookeeper02 启动 ----------------
ZooKeeper JMX enabled by default
Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
-------------- zookeeper03 启动 ----------------
ZooKeeper JMX enabled by default
Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[wangzhou@zookeeper01 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: leader
-------------- 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: follower
[wangzhou@zookeeper01 bin]$ ./zk.sh stop
-------------- zookeeper01 停止 ----------------
ZooKeeper JMX enabled by default
Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED
-------------- zookeeper02 停止 ----------------
ZooKeeper JMX enabled by default
Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED
-------------- zookeeper03 停止 ----------------
ZooKeeper JMX enabled by default
Using config: /home/wangzhou/Downloads/zookeeper-3.5.7/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED

0 人点赞