Zookeeper集群

zookeeper有两种工作的模式,一种是单机方式,另一种是集群方式;
Zookeeper作为一个服务,它本身也可能发生故障,所以我们需要将Zookeeper进行集群,避免单点故障问题,以保证zookeeper本身的高可用性;

Zookeeper集群特点

Zookeeper集群有三个角色,一个leader(领导者),一个follower(跟随者),一个observer(观察者);
集群中只要有 超过半数 的机器是正常工作的,那么整个集群对外就是可用的;
也就是说如果有2个zookeeper,那么只要有1个故障了,zookeeper就不能用了,因为1没有过半,所以2个zookeeper不是高可用的,因为不能容忍任何1台发生故障;
同理,要是有3个zookeeper,一个故障了,还剩下2个正常的,超过半数了,所以3个zookeeper才是高可用的,因为能容忍1台发生故障;
如果是4台、5台、6台呢?那么分别能容忍1,2,2 台发生故障;

最后结论:zookeeper集群需要奇数(3,5,7,9,11…)台服务器实现;

1.zookeeper集群配置

由于我之前安装过:

Zookeeper集群
直接拷贝3个文件

Zookeeper集群

2. 3个zookeeper中conf目录下的zoo_sample.cfg复制一份,改为zoo.cfg
Zookeeper集群
3. 3个zookeeper中conf目录下的zoo_sample.cfg复制一份,改为zoo.cfg并配置:
dataDir=/usr/local/apache-zookeeper-3.5.5-bin-01/data
clientPort=2181

Zookeeper集群

#zookeeper内嵌的server服务器的端口,默认是8080
admin.serverPort=3181((zookeeper从3.5.x版本开始会占用8080端口,通过此配置修改掉默认的8080,避免和tomcat端口冲突))

server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890
格式:
server.A = B:C:D:
server.serverid = serverhost:leader_listent_port:quorum_port
A是一个数字,表示这个是第几号服务器,
B是这个服务器的ip地址
C该端口用于集群成员的信息交换,表示的是该服务器与集群中的Leader服务器交换信息的端口
D是在leader挂掉时专门用来进行选举leader端口

4.创建三个dataDir目录

/usr/local/apache-zookeeper-3.5.5-bin-01/data
/usr/local/apache-zookeeper-3.5.5-bin-02/data
/usr/local/apache-zookeeper-3.5.5-bin-03/data

每个data目录中都创建一个名为myid的文件,3个文件的内容分别写1、2、3;

如果你这个dataDir目录下有原来运行产生的数据,最好是删除一下;
这个1、2、3是对应前面的server.1server.2server.3
至此一个zookeeper的集群就搭建完成;其他2台根据以上步骤改下

2.测试验证

1.进入Zookeeper集群中bin目录启动3台zookeeper

查看第3台:(leader)

Zookeeper集群

查看第2台(follower):

Zookeeper集群
查看第一台:

Zookeeper集群

如果是单机模式:

Zookeeper集群
mode有显示standalone说明集群没有搭建成功可以看logs目录下的日志

3.zookeeper集群原理

Leader选举是保证分布式数据一致性的关键所在,当Zookeeper集群中的一台服务器出现以下两种情况之一时,需要进入Leader选举。
(1) 服务器初始化启动的时候;
(2) 服务器运行期间无法和Leader保持连接;

1、服务器启动初始化的时候Leader选举
进行Leader选举的基础条件是至少需要有两个zookeeper,下面我们以3台机器组成的zookeeper集群为例。
在集群初始化阶段,当有一台服务器zookeeper1启动时,其单独无法进行和完成Leader选举;
当第二台服务器zookeeper2启动时,此时两台机器(超过半数)可以相互通信,每台机器都试图找到Leader,于是进入Leader选举过程,选举过程如下:
(1) 每个zookeeper发出一个投票,由于是启动初始情况,zookeeper1和zookeeper2都会将自己作为Leader服务器来进行投票,每次投票会包含所推选的服务器的myid和ZXID,使用 (ZXID,myid) 来表示,此时zookeeper1的投票为 (0, 1),zookeeper2的投票为 (0, 2),然后各自将这个投票信息发送给集群中其他机器。

(2) 集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器。

LOOKING
寻找leader状态
当前服务器处于该状态时,它会认为当前集群中没有leader,因此需要进入leader选举状态。

FOLLOWING
跟随者状态
表示当前服务器的角色是Follower角色

LEADING
领导者状态
表示当前服务器是Leader

OBSERVING
观察者状态
表示当前服务器角色是Observer;
(3) 处理投票,针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK规则如下:
优先检查ZXID,ZXID比较大的服务器优先作为Leader;(相等,都是0)
如果ZXID相同,那么就比较myid,myid大的服务器作为Leader服务器;

对于zookeeper1而言,它的投票是 (0, 1),接收zookeeper2的投票为 (0, 2,),首先会比较两者的ZXID,均为0,再比较myid,此时zookeeper2的myid最大,zookeeper2成为leader,同时每个zookeeper更新自己的投票为 (0,2),然后重新投票,对于zookeeper2而言,其无须更新自己的投票,只是再次向集群中所有机器发送上一次投票信息即可;

(4) 统计投票,每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于zookeeper1、zookeeper2而言,都统计出集群中已经有两台机器接受了 (0,2) 的投票信息, 此时便认为已经选出了Leader;
(5) 改变服务器状态,一旦确定了Leader,每台服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING。

2、服务器运行期间的Leader选举
在Zookeeper运行期间,Leader与非Leader服务器各司其职,如果有非Leader服务器宕机或新加入,此时不会影响Leader,但是一旦Leader服务器宕机,那么整个集群将暂停对外服务,进入新一轮Leader选举,其过程和启动时期的Leader选举过程基本一致;假设正在运行的有zookeeper1、zookeeper2、zookeeper3三台服务器,当前Leader是zookeeper2,若某一时刻Leader宕机了,此时便开始Leader选举,选举过程如下:

(1) 变更状态,Leader宕机后,余下的服务器都会将自己的服务器状态变更为LOOKING,然后开始进入Leader选举过程;

(2) 每个zookeeper会发出一个投票,在运行期间,每个服务器上的ZXID可能不同,此时假定zookeeper1的ZXID为128,zookeeper3的ZXID为127;在第一轮投票中,zookeeper1和zookeeper3都会将票投给自己,产生投票(128, 1),(127, 3),然后各自将投票发送给集群中其他机器;

(3) 接收来自各个服务器的投票,与自己的投票进行比较,此过程与启动时相同;

(4) 处理投票,与启动时过程相同,此时(zookeeper1将会成为Leader);

(5) 统计投票,与启动时过程相同。

(6) 改变服务器的状态,与启动时过程相同。

4.Zookeeper集群角色分工

Zookeeper有三个角色:领导者、跟随者、观察者,不同角色来执行不同的任务。
首先梳理几个概念:
1. 事务请求:
在zk中,那些会改变服务器状态的请求称为事务请求(创建节点、更新数据、删除节点、创建会话等等)
2. 非事务请求
从zk读取数据,但是不对状态进行任何修改的请求称为非事务请求;

Leader角色
Leader服务器是zk集群工作的核心,其主要工作有两个:

  1. 事务请求的唯一调度者和处理者,保证集群事务处理的顺序性;
  2. 集群内部各个服务器的调度者;

Follower角色
Follower是zk集群的跟随者,其主要工作有三个:

  1. 处理客户端非事务性请求,转发事务请求给Leader服务器(事务请求都由Leader处理)
  2. 参与事务请求的投票
  3. 参与Leader选举投票

Observer角色
Observer充当观察者角色;Observer观察者是另一种跟随者;

  1. 观察zk集群的最新状态变化并将这些状态同步过来;
  2. 对于非事务请求可以进行独立的处理,对于事务请求,则会转发给Leader服务器进行处理;
  3. Observer不会参与任何形式的投票,包括事务请求的投票和Leader选举的投票;

如何配置observer模式?

在任何想变成observer模式的配置文件中加入如下配置:
peerType=observer
并在所有server的配置文件中,配置成observer模式的server的那行配置追加:observer,例如:
peerType=observer
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890
server.4=localhost:2891:3891:observer

为什么有Observer角色?

我们知道ZooKeeper的ZNode变更是要过半数投票通过,随着机器的添加,因为网络消耗等原因必定导致投票成本增加,从而导致写性能的下降。
Observer是一种新型的ZooKeeper节点,能够帮助解决上述问题,提供ZooKeeper的可扩展性。Observer不參与投票,仅仅是简单的接收投票结果。因此我们添加再多的Observer,也不会影响集群的写性能。除了这个区别,其它的和Follower基本上全然一样。比如:Client都能够连接到他们(Observer),而且都能够发送读写请求给他们,收到写请求都会上报到Leader。
Observer有另外一个优势,由于它不參与投票,所以他们不属于ZooKeeper集群的关键部位,即使他们Failed,或者从集群中断开,也不会影响集群的可用性。

Zookeeper集群Zookeeper集群 qq_320253624 发布了133 篇原创文章 · 获赞 17 · 访问量 1万+ 私信 关注
上一篇:PHP array_diff 计算数组的差集


下一篇:设计模式 之 Template,Strategy,State,Observer,Memento,Mediator,Command,Visitor,Chain of Responsibility