zookeeper原理解析

zookeeper学习

为什么需要zookeeper,zookeeper作用是什么?

Zookeeper主要用于分布式系统中,为了提供高可用的服务,作用主要包括两点:

  • 1)在主备节点之间选举主节点
  • 2)在发生宕机重启等意外情况时,使某个值达成一致,保证不论发生以上任何异常,都不会破坏决议一致性。

zookeeper使用实例

  1. 在kafaka集群中,通过Zookeeper管理集群配置,选举leader,以及在consumer group发生变化时进行rebalance
  2. Hadoop,使用Zookeeper的事件处理确保整个集群只有一个NameNode,存储配置信息等.
  3. 3HBase,使用Zookeeper的事件处理确保整个集群只有一个HMaster,察觉HRegionServer联机和宕机,存储访问控制列表等.

Zookeeper原理

Zookeeper中的角色:
Leader:领导者,负责进行投票的发起和决议,更新系统状态
Learner:
   Follower:追随者接收客户请求并向客户端返回结果,在选主过程中进行投票
   Observer:观察者不参与投票,仅同步leader的状态。目的是为了扩展系统,提高读取速度。
Client:请求发起方

Zookeeper中节点在工作过程中有三种状态:

    LOOKING:当前Server不知道leader是谁,正在搜寻

    LEADING:当前Server即为选举出来的leader

    FOLLOWING:leader已经选举出来,当前Server与之同步

Zookeeper与客户端

zookeeper与客户端

zookeeper原理解析_第1张图片

 

 

动物园管理员节点数据操作流程

zookeeper原理解析_第2张图片

整体流程如下:

1.在客户端向Follwer发出一个写的请求

2.Follwer把请求发送给负责人

3.Leader接收到以后开始发起投票并通知Follwer进行投票

4.Follwer把投票结果发送给负责人

5.Leader将结果汇总后如果需要写入,则开始写入同时把写入操作通知给负责人,然后提交;

6.Follwer把请求结果返回给客户端

 

Paxos的算法

基于消息传递通信模型的分布式系统,不可避免的会发生以下错误:进程可能会慢,被杀死或者重启,消息可能会延迟,丢失,重复,在基础Paxos场景中,先不考虑可能出现消息篡改即拜占庭错误(Byzantine failure,即虽然有可能一个消息被传递了两次,但是绝对不会出现错误的消息)的情况.Paxos算法解决的问题是在一个可能发生上述异常的分布式系统中如何就某个值达成一致,保证不论发生以上任何异常,都不会破坏决议一致性。

Paxos算法使用一个希腊故事来描述,在Paxos中,存在三种角色,分别为

  • Leader(提议者,用来发出提案 proposal)
  • Follower(接受者,参与投票,可以接受或拒绝提案)
  • Observer(观察者,不参与投票,学习被选定的提案,当提案被超过半数的 Acceptor 接受后为被批准)

  下面更精确的定义Paxos要解决的问题:

1,决议(价值)只有在提议者提出后才能被批准

2,在一次Paxos算法的执行实例中,只批准(选择)一个值

3,学习者只能获得被批准(选择)的价值

 

ZooKeeper的选举算法有两种:一种是基于Basic Paxos(Google Chubby采用)实现的,另外一种是基于Fast Paxos(ZooKeeper采用)算法实现的。系统默认的选举算法为Fast Paxos。并且ZooKeeper在3.4 .0版本后只保留了FastLeaderElection算法。

ZooKeeper的核心是原子广播,这个机制保证了各个服务器之间的同步。实现这个机制的协议叫做ZAB协议(Zookeeper Atomic BrodCast).ZAB协议有两种模式,它们分别是崩溃恢复模式(选主)和原子广播模式(同步)。

1,当服务启动或者在领导者崩溃后,ZAB就进入了恢复模式,当领导者被选举出来,且大多数服务器完成了和领导的状态同步以后,恢复模式就结束了。状态同步保证了领导者和跟随者之间具有相同的系统状态。

 2,当ZooKeeper集群选举出领导同步完状态退出恢复模式之后,便进入了原子广播模式。所有的写请求都被转发给领导者,再由领导者更新提议广播给追随者

   为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(提议)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是时代用来标识领导关系是否改变,每次一个领导被选出来,它都会有一个新的时代,标识当前属于那个领导者的统治时期。低32位用于递增计数。 

ZooKeeper的集群选主实例

  以一个简单的例子来说明整个选举的过程:假设有五台服务器组成的zookeeper集群,它们的serverid从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来看看会发生什么

1,服务器1启动,此时只有它一台服务器启动了,它发出去的报没有任何响应,所以它的选举状态一直是看状态

2,服务器2启动,它与最开始启动的服务器1进行通信,互相交换自己的选举结果,由于两者都没有历史数据,所以id值较大的服务器2胜出,但是由于没有达到超过半数以上的服务器都同意选举它(这个例子中的半数以上是3),所以服务器1,2还是继续保持查看状态

3,服务器3启动,根据前面的理论分析,服务器3成为服务器1,2,3中的老大,而与上面不同的是,此时有三台服务器(超过半数)选举了它,所以它成为了这次选举的领导者

4,服务器4启动,根据前面的分析,理论上服务器4应该是服务器1,2,3,4中最大的,但是由于前面已经有半数以上的服务器选举了服务器3,所以它只能接收当小弟的命了

5,服务器5启动,同4一样,当小弟

ZooKeeper的非全新集群选主

  那么,初始化的时候,是按照上述的说明进行选举的,但是当动物园管理员运行了一段时间之后,有机器下降,重新选举时,选举过程就相对复杂了。

需要加入数据version,serverid和逻辑时钟。

version:数据新的版本就大,数据每次更新都会更新版本

server id:就是我们配置的myid中的值,每个机器一个

逻辑时钟:这个值从0开始递增,每次选举对应一个值,也就是说:如果在同一次选举中,那么这个值应该是一致的;逻辑时钟值越大,说明这一次选举领导者的进程更新,也就是每次选举拥有一个zxid​​,投票结果只取zxid最新的

选举的标准就变成:
    1、逻辑时钟小的选举结果被忽略,重新投票
    2、统一逻辑时钟后,数据 version 大的胜出
    3、数据 version 相同的情况下,server id 大的胜出
 根据这个规则选出 leader。

raft算法

和Paxos的类似,区别如下两点:

raft是基于对多paxos的两个限制形成的:

  • 发送的请求的是连续的,也就是说raft的追加操作必须是连续的。而paxos可以并发的。(其实这里并发只是追加日志的并发提高,应用的状态机还是必须是有序的)
  • 选主是有限制的,必须有最新,最全的日志节点才可以当选。而多paxos是随意的所以raft可以看成是简化版本的多paxos(这里多paxos因为允许并发的写日志,因此不存在一个最新,最全的日志节点,因此只能这么做。这样带来的麻烦就是选主以后,需要将主里面没有的log给补全,并执行commit过程)

思考个问题:

为什么需要2N + 1台服务器,发生了宕机,什么情况下会不能使用?

首先只有一个服务器会不稳定,服务器宕机系统就瘫了,2或偶数个的话,脑裂出现,并且分化成的两个集群机器数量均为n,一半选举这个另一半选举那个,此时无法决断,无法进行选举和作出决议,但是如果是奇数个,两个集群机器必然有一多一少,此时以多的为准即可。所以leader选举,要求 可用节点数量 > 总节点数量/2。

2n + 1个台服务器,只要有n + 1个台就可以使用。也就是你说的少于一半集群就无效了

你可能感兴趣的:(分布式系统)