Zookeeper 总结

简介

Zookeeper最初是由雅虎开发,后来捐献给了apache。zookeeper是一个分布式协调服务,在很多分布式服务和框架中被广泛使用,主要的应用方向有两个,一个是配置管理,一个是节点协调,比如主从选择等。此外,zookeper还能实现跟多其他的功能,比如分布式队列、分布式锁等等,对于分布式队列,由于zookeeper不是一个数据服务,所以对应这类数据操作比较频繁的场景,很少被采用,只是说它能够同步自己身的特性去实现这个功能。

paxos算法

提到zookeeper,就不得不提paxos算法,在zookeeper原理与实战那边中对paxos算法有介绍。paxos算法是一个分布式一致性算法,它主要解决的问题是实现在分布式环境下的数据一致性。但是,需要注意的是,paxos算法工作的前提是不存在拜占庭将军问题,拜占庭将军问题说的是在不可靠信道上通过消息传递的方式想就某个决议达成一致是不可能的,也就是paxos算法的前提是在通信信道上传递的消息不会被篡改。

paxos算法中设计到三个主要的角色,分别proposer、leader、acceptor,其中,proposer是提案的发起者,acceptor是提案的接收者或者说是裁决者,leader是提案的同步者,paxos算法主要包含两个节点,分别是prepare阶段和accept阶段,下面来简单描述一下paxos算法的执行过程。

首先是prepare阶段,proposer发起一次提案,一个提案会有一个全局唯一的递增ID与之关联,proposer将prepare(n)发送给所有的acceptor,acceptor接收到提案以后,会与存储在本地的曾经接收过的提案的最大编号MaxN进行比较,如果n大于maxn则此次提案可以通过,如果小于,则说明此次提案已经过期,如果过期,那么acceptor不会向proposer进行反馈,如果没有过期,则acceptor会向proposer进行反馈,表示同意通过本次提案,当有超半数acceptor同意此次提案后,就会进入到accept阶段,在accept阶段,proposer会将之前给予反馈的所有acceptor发送提案的真正内容,acceptor在接收到提案后,还会对此次提交的提案对应的编号N进行验证,如果合法,则反馈proposer一个ack消息,当proposer接收到半数以上的ack消息后,就会向集群中广播两种消息,一种是commit消息,通知那些已经返回ack的acceptor提交这次提案,另外是提案+commit的消息,通知没有通过或没有反馈ack消息的acceptor强制执行本地提案并直接提交,以上就是paxos算法的一般过程。

但是由于在通用的paxos算法中,所有节点都可以进行提案的提交,会造成活锁问题,也就是说,可能一个proposer提交的提案由于提交时机的问题,一直没有被通过,那么这个proposer就会进入死循环状态出不来,也即是活锁,所以在paxos算法的基础上人们提出了一些优化的paxos算法,比fast paxos和epaxos,在fast paxos算法中,规定了只有一个节点能够进行提案的提交,这样就避免了活锁问题。

zab协议

zab协议是zookeeper atomic broadcast的简写,也就是zk原子广播协议,zab是基于paxos算法实现的,zookeeper通过zab协议来保证zookeeper集群中数据的一致性。

leader选举

由于zookeeper采用master -slave架构,所以在所有节点中就需要选出一个master节点,这个master节点就是leader,在zk中,节点类型主要分为三种,分别是leader、follower和observer,其中leader对应paxos算法中的proposer,而follower对应acceptor,follower+observer对应的leader,follower和observer的区别在于observer只进行数据同步和读请求的处理,而不参与leader选举,主要值为了提升zookeeper集群的性能,分担follower的压力。

而zookeeper集群中节点的状态主要有leading、following、observoring和looking,leader选举主要有两种情景,一种是新集群的leader选举,一种是当leader宕机时的leader选举,这两种情况的大体流程是一样的,只是有一些小的区别。

首先来说一说新集群启动时的leader选举过程。当启动一个节点是,这个节点处于looking状态,并且由于没有其他节点所以此时无法进行leader选举,当又另外一个节点启动时,leader选举就开始了,首先每个节点会向集群中的其他节点发送一个有myid和zxid组成的消息,即(myid,zxid),然后每个节点会对其受到的消息进行判断比较,比较的规则是首先比较zxid,如果zxid比较大的话,会优先选择它作为leader,如果zxid相同,那么就会现在muyid较大的那个作为leader,由于这两个节点都是新节点,所以zxid都为null,最终就会选择myid比较大的那个作为leader,当超过半数节点选择这个节点作为leader后,首先它会将自己的状态从looking变为leading,然后同步自己的epach信息给其他节点,其他节点同步leader的数据完成后,会将自己的状态从looking该为following,如果右observer的话就会从looking变为observering状态。以上就是一个新集群的leader选举过程。

下面在说说leader宕机后的选举过程,实际上过程基本一样,唯一的区别在于,当leader宕机以后,follower和observer会将自身状态从following、observering改为looking状态,然后再进行与上述过程一样的leader选举过程,比较zxid和myid,然后进行投票统计,最终选出leader,然后进行epach同步,最终修改自身的状态,最终集群进入服务状态。

zookeeper与cap关系

从上述选举过程我们可以看出,在leader选举的过程中,服务是不可用的,所以zookeeper实际上是一个满足了cp的分布式系统,也就是说或它牺牲了可用性,保证了数据的一致性,与之相对应的例如spring cloud中的eureka以及rocktmq中的nameserver都是满足了ca而牺牲了cp,也即是满足了服务的可用性但是牺牲了数据的一致性。

一个分布式系统不可能同时满足cap的三个方面。

zookeeper中的节点

znode是zookeeper中的最小数据单元,znode可以理解为磁盘文件路径中的文件夹,只不过这个文件夹本身可以存储数据。znode主要分为临时顺序节点、持久顺序节点、临时节点和持久节点,对于临时节点来说,如果客户端与zk之间的tcp长连接端断开了,那么这个临时节点就会被自动删除,这个特性在锁的场景中以及集群主备切换的场景中非常有用。

同时,zk还支持在znode上设置监听,也即是我们所说的watcher,可以简单节点数据的变化,子节点的变化,节点的删除等时间,从事通过事件进行回调来通知客户端进行相应的操作,比如在一个主从集群中,一个节点会对应与zk中的一个临时节点,所有的slave会监听master节点的删除事件,如果master节点宕机,那么这个master对应的临时节点就会被zk自动删除,从事触发了在这个节点上的watcher,这时所有的slave节点就知道master宕机了,就会主动master的竞争选举,最终选出一个新的master节点。

zookeeper的java客户端

zk的java客户端主要有两种,一种是zkClient,一种的curator,其中zkClient是一种比较原始的api,操作起来比较麻烦,而curator是对zkClient的封装,使用起来会更加方便。

zookeeper的使用场景

  • 配置信息维护
  • 命名服务
  • 分布式同步锁
  • 集群管理
  • 分布式队列
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值