Zookper 选举机制及原理

  • Post author:
  • Post category:其他


  1. 什么是Zookeeper?

(1)分布式的协调服务,开源,主要作用为分布式应用提供一致性服务。在java中常用语服务的注册中心。

(2)zookeeper=文件系统+通知机制

2.zookper三种角色

Leader(领导者):为客户端提供读和写操作,负责投票的发起和决议,更新系统状态。Zookeeper中推选Leader 就是为了保持数据的一致性,都已leader节点上的数据为准。

Foller(跟随者):为客户端提供读服务,负责投票的发起和决议更新状态系统,若接收到写服务则转发给Leader。

Observe :作用于Flolower一样但是不参与投票。

  1. Leader选举

(1)Leader选举(票数大于总服务器一般的服务器为Leader)

Eg:

​                  A         B             C             D          E

第一次    A启动   A———A

第二次    B启动    A———A

B———B

无法选出Leader,更改投票信息(Serverid小投给Serverid大的)

A——-B

B——-B          无法选出

第三次    C启动     C——-C          无法选出

更改投票  A——-C

B——–C

C———-C   ,C获得3票,为Leader。

D,E启动,不需要选了。

(2)关于脑裂

1.防止由脑裂造成的集群不可用。

  • 假如zookeeper集群有 5 个节点,发生了脑裂,脑裂成了A、B两个小集群:

​     (a) A : 1个节点 ,B :4个节点 , 或 A、B互换

​     (b) A : 2个节点, B :3个节点  , 或 A、B互换

② 假如zookeeper集群有4个节点同样发生脑裂,脑裂成了A、B两个小集群:

​    (a) A:1个节点 ,  B:3个节点,   或 A、B互换

​    (b) A:2个节点 , B:2个节点

​    什么是脑裂?

​    集群中出现了两个Leader。

​    为什么会出先这种情况

​ZooKeeper内部通过心跳机制来确定leader的状态,由于网络原因,导致心跳监测超时。

1. 这时follower认为leader出现了故障,但是leader节点并没有故障,这就是假死状态。

2. leader节点假死后,ZooKeeper通知所有follower节点进行选举。这时出现一个新leader,这时集群中就出现了两个leader。

3. ZooKeeper将新leader信息通知给所有的follower节点和client。

4. 如果部分client获得了新的节点信息,而部分没有获得,这时client向ZooKeeper发送写请求时,ZooKeeper内部就会出现不一致。

解决方案:

1. Quorums法:通过设置法定人数, 进而确定集群的容忍度, 当集群中存活的节点少于法定人数, 集群将不可用

2. 冗余通信:集群中采用多种通信方式, 防止一种通信方式失效导致集群中的节点无法通信.

3. 通过共享资源的方式, 将所有共享资源添加到集群中, 能对共享资源进行写操作(即加锁)的节点就是leader节点.

ZooKeeper默认采用了Quorums的方式。

具体解决思路:ZooKeeper维护了一个叫epoch的变量, 每当新leader产生时, epoch都会递增, followers如果确认了新的leader存在, 同时也会知道其epoch的值 —— 它们会拒绝epoch小于现任leader的epoch的所有旧leader的任何请求.

(3)在容错能力相同的情况下,奇数台更节省资源。**

#### ZooKeeper 的读写机制

Zookeeper是由多个server组成的集群,一个leader,多个follower,每个server保存一份数据副本,数据是一致的,分布式读写, 更新请求转发,由leader实施。更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行(FIFO机制)。数据更新原子性,一次数据更新要么成功,要么失败。

写流程:

![1564397760105](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1564397760105.png)

(1)Client向Zookeeper的server1发送一个写请求,客户端写数据到服务器1上;

(2)如果server1不是Leader,那么server1会把接收到的写请求转发给Leader;然后Leader会将写请求转发给每个server;

(3)当Leader收到集群半数以上的节点写成功的消息后,说明该写操作执行成功;

(4)被访问的server1进一步通知client数据写成功,这时,客户端就知道整个写操作成功了。

#### Zookeeper Shell

– 启动ZK服务: zkServer.sh start

– 查看ZK状态: zkServer.sh status

– 停止ZK服务: zkServer.sh stop

– 重启ZK服务: zkServer.sh restart

#### Zookeeper API

连接服务器:ZooKeeper(String connectString,int sessionTimeout,Watcher watcher)

创建节点:String create(final String path,byte[] data,List<ACL>acl,CreateModel createModel);

删除节点:void delete(final String path,int version);

3个节点,需要两个节点存活才能正常工作,允许一台出现宕机。

​    4个节点,需要3和节点存活才能正常工作。 允许一台出现宕机。



版权声明:本文为weixin_40329367原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。