前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >zookeeper入门到精通04——zookeeper集群选举与集群操作

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

作者头像
用户10127530
发布2022-10-26 17:55:11
2520
发布2022-10-26 17:55:11
举报
文章被收录于专栏:半旧的技术栈半旧的技术栈

4.zookeeper集群选举与集群操作

4.1 集群选举机制
4.1.1 第一次启动

这里假设有5台服务器。

image-20220404114114596
image-20220404114114596
image-20220404114435155
image-20220404114435155
image-20220404114503440
image-20220404114503440
image-20220404114709167
image-20220404114709167
image-20220404114812605
image-20220404114812605

其实我们稍微总结一下,原来第一次选举就是选举myid 在中位的那台服务器啊,果然大佬都是站在c位的。但是这是有条件的,条件就是我们按照myid的顺序来启动服务器,如果不是那这个规律就不成立,只能够总结成为超过半数人参与选举的情况下,出身最好(myid最大)的当老大。这里如果觉得有疑问,可以自己按照上面讲的过程推算一下。

客户端可以给zookeeper服务集群进行写操作,每一次写操作都可以看作一次事务,这里有几个概念后续可能用到,简单介绍如下。

image-20220404115608623
image-20220404115608623

SID很好懂,zxid就是事务ID,客户端的每一次发送事务请求都会提交一个版本号,这个数值越大,说明服务器的版本越新。

这里Epoch可能会比较难懂,服务器每次参加一次选举Epoch就会+1,这就像是一个朝代中元老们的资历,而当选leader的一定是他们中Epoch最大的那个,因此它也可以说是一个Leader任期的代号,后续将结合案例具体介绍。

4.1.2 非第一次启动

您可以先大概看下下面的图片,看不懂没关系,我将拆解进行介绍。

image-20220404121546579
image-20220404121546579

首先我们思考一个问题,为什么要选举出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
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-04-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4.zookeeper集群选举与集群操作
    • 4.1 集群选举机制
      • 4.1.1 第一次启动
      • 4.1.2 非第一次启动
    • 4.2 zookeeper启动停止脚本
      • 4.2.1 脚本编写
      • 4.2.2 脚本测试
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档