目录
zookeeper 全新集群选举机制网上资料很多说法很模糊,仔细思考了一下,应该是这样
得到票数最多的机器>机器总数半数
具体启动过程中的哪个节点成为 leader 与 zoo.cfg 中配置的节点数有关,下面以3个举例
机器总数对应在 zoo.cfg 中配置如下形式配置节点信息
server.X=A:B:C
X 代表当前机器在整个架构中的序号,是整数
A 代表第X个节点的ip地址
B 代表第X个节点与 leader 节点交换信息的端口
C 表示万一 leader 节点宕机,需要C这个端口在多个 follower 之间进行选举,选出一个新的 leader,用来进行选举时节点之间相互通信的端口
集群节点数量计算公式
y=2x+1,x为正整数,y为节点数
为什么是奇数?之前写过一篇文章
https://blog.csdn.net/zlpzlpzyd/article/details/132716450
很多说法是按照5个节点来讲的,按照公式来讲三个应该可以。
下面就来试一下
在自己的机器上安装 zookeeper
分别为 master、node1、node2
zoo.cfg
- sudo tee conf/zoo.cfg <<-'EOF'
- tickTime=2000
- initLimit=10
- syncLimit=5
- dataDir=/opt/zookeeper
- clientPort=2181
- server.1=master:2888:3888
- server.2=node1:2888:3888
- server.3=node2:2888:3888
- EOF
各个节点的 zoo.cfg 文件内容一致。各个节点 dataDir 中文件 myid 内容如下。
master
echo 1 > /opt/zookeeper/myid
node1
echo 2 > /opt/zookeeper/myid
node2
echo 3 > /opt/zookeeper/myid
先启动两个节点,看看情况
- [root@master apache-zookeeper-3.9.0-bin]# ./bin/zkServer.sh start
- ZooKeeper JMX enabled by default
- Using config: /opt/apache-zookeeper-3.9.0-bin/bin/../conf/zoo.cfg
- Starting zookeeper ... STARTED
- [root@node1 apache-zookeeper-3.9.0-bin]# ./bin/zkServer.sh start
- ZooKeeper JMX enabled by default
- Using config: /opt/apache-zookeeper-3.9.0-bin/bin/../conf/zoo.cfg
- Starting zookeeper ... STARTED
- [root@master apache-zookeeper-3.9.0-bin]# ./bin/zkServer.sh status
- ZooKeeper JMX enabled by default
- Using config: /opt/apache-zookeeper-3.9.0-bin/bin/../conf/zoo.cfg
- Client port found: 2181. Client address: localhost. Client SSL: false.
- Mode: follower
- [root@node1 apache-zookeeper-3.9.0-bin]# ./bin/zkServer.sh status
- ZooKeeper JMX enabled by default
- Using config: /opt/apache-zookeeper-3.9.0-bin/bin/../conf/zoo.cfg
- Client port found: 2181. Client address: localhost. Client SSL: false.
- Mode: leader
配置了三个节点,只启动了两个节点的情况下,正常选举,符合想法。说明3个节点中有两个节点启动就可以完成选举流程。
下面再启动 node2
- [root@node2 apache-zookeeper-3.9.0-bin]# ./bin/zkServer.sh start
- ZooKeeper JMX enabled by default
- Using config: /opt/apache-zookeeper-3.9.0-bin/bin/../conf/zoo.cfg
- Starting zookeeper ... STARTED
- [root@node2 apache-zookeeper-3.9.0-bin]# ./bin/zkServer.sh status
- ZooKeeper JMX enabled by default
- Using config: /opt/apache-zookeeper-3.9.0-bin/bin/../conf/zoo.cfg
- Client port found: 2181. Client address: localhost. Client SSL: false.
- Mode: follower
符合上面的推测
突发奇想,两个节点会是什么情况?
个人猜测,跟上面两个节点启动一致。
分别为 master、node1
zoo.cfg
- sudo tee conf/zoo.cfg <<-'EOF'
- tickTime=2000
- initLimit=10
- syncLimit=5
- dataDir=/opt/zookeeper
- clientPort=2181
- server.1=master:2888:3888
- server.2=node1:2888:3888
- EOF
各个节点的 zoo.cfg 文件内容一致。
- [root@master apache-zookeeper-3.9.0-bin]# ./bin/zkServer.sh start
- ZooKeeper JMX enabled by default
- Using config: /opt/apache-zookeeper-3.9.0-bin/bin/../conf/zoo.cfg
- Starting zookeeper ... STARTED
- [root@node1 apache-zookeeper-3.9.0-bin]# ./bin/zkServer.sh start
- ZooKeeper JMX enabled by default
- Using config: /opt/apache-zookeeper-3.9.0-bin/bin/../conf/zoo.cfg
- Starting zookeeper ... STARTED
- [root@master apache-zookeeper-3.9.0-bin]# ./bin/zkServer.sh status
- ZooKeeper JMX enabled by default
- Using config: /opt/apache-zookeeper-3.9.0-bin/bin/../conf/zoo.cfg
- Client port found: 2181. Client address: localhost. Client SSL: false.
- Mode: follower
- [root@node1 apache-zookeeper-3.9.0-bin]# ./bin/zkServer.sh status
- ZooKeeper JMX enabled by default
- Using config: /opt/apache-zookeeper-3.9.0-bin/bin/../conf/zoo.cfg
- Client port found: 2181. Client address: localhost. Client SSL: false.
- Mode: leader
最终结果如上面猜测。
有一个问题比较奇怪,启动后只有 leader 节点绑定了 2888 端口,其他 follower 节点没绑定。
- [root@master zookeeper]# netstat -tunlp | grep 6244
- tcp6 0 0 :::2181 :::* LISTEN 6244/java
- tcp6 0 0 :::42279 :::* LISTEN 6244/java
- tcp6 0 0 192.168.0.70:3888 :::* LISTEN 6244/java
- tcp6 0 0 :::8080 :::* LISTEN 6244/java
- [root@node1 zookeeper]# netstat -tunlp | grep 9409
- tcp6 0 0 192.168.0.73:2888 :::* LISTEN 9409/java
- tcp6 0 0 192.168.0.73:3888 :::* LISTEN 9409/java
- tcp6 0 0 :::8080 :::* LISTEN 9409/java
- tcp6 0 0 :::2181 :::* LISTEN 9409/java
- tcp6 0 0 :::37957 :::* LISTEN 9409/java
- [root@node2 zookeeper]# netstat -tunlp | grep 17645
- tcp6 0 0 192.168.0.79:3888 :::* LISTEN 17645/java
- tcp6 0 0 :::8080 :::* LISTEN 17645/java
- tcp6 0 0 :::2181 :::* LISTEN 17645/java
- tcp6 0 0 :::36683 :::* LISTEN 17645/java
去看一下官方文档
ZooKeeper: Because Coordinating Distributed Systems is a Zoo
For replicated mode, a minimum of three servers are required, and it is strongly recommended that you have an odd number of servers. If you only have two servers, then you are in a situation where if one of them fails, there are not enough machines to form a majority quorum. Two servers are inherently less stable than a single server, because there are two single points of failure.
对于集群节点,最少的 server 数量是三个, 强烈建议是奇数。如果是两个 server,当其中一个节点有故障,没有足够的机器进行优先级处理。
符合上面的最少三个节点的理论。