ZooKeeper作用是什么?

用户69288316


Zookeeper的主要有四个作用:


  • 配置管理

  • 名字服务

  • 提供分布式同步

  • 集群管理

配置管理

在我们的应用中,会有一些配置项是写在

application.properties

文件里的,代码中通过@Value读取对应的值,如果配置非常多,而且还可能是动态的话使用配置文件就需要重启服务。这个时候往往需要寻找一种集中管理配置的方法,我们在这个集中的地方修改了配置,所有对这个配置感兴趣的都可以获得变更。

这个时候就需要使用一种实现了一致性协议的服务了。Zookeeper就是这种服务,它使用Zab(原子广播协议)来提供一致性。现在有很多开源项目使用Zookeeper来维护配置,比如在消息队列Kafka中,使用Zookeeper来维护broker的信息。在Alibaba开源的SOA框架Dubbo中也广泛的使用Zookeeper管理一些配置来实现服务治理。

名字服务

我们大家应该都知道DNS这个东西。我们只需要访问一个大家熟知的站点,它就会告诉你这个域名对应的IP是什么。我们的应用中也会存在很多这类问题,特别是在我们的服务特别多的时候,如果我们在本地保存服务的地址将非常不方便,但如果我们只需要访问一个大家都熟知的endpoint,这里提供统一的入口,那么维护起来将方便得多。

分布式锁

可以利用Zookeeper来协调多个分布式进程之间的活动。比如在一个分布式环境中,为了提高可靠性,集群的每台服务器上都部署着同样的服务。但是,一件事情如果集群中的每个服务器都进行的话,那相互之间就要协调,编程起来非常复杂。如果我们只让一个服务进行操作,那又存在单点。

通常的做法就是使用分布式锁,在某个时刻只让一个服务去工作,当这个服务出问题时释放锁,立即fail over到另外的服务,即Leader Election(leader选举)机制。比如HBase的Master就是采用这种机制。需要注意的是分布式锁跟同一个进程的锁还是有区别的,所以使用的时候要比同一个进程里的锁更谨慎的使用。

集群管理

在分布式集群中,经常有各种原因,比如硬件故障,软件故障,网络问题,有新的节点加入进来,也有老的节点退出集群。这时,集群中其他机器需要感知到这种变化,然后根据这种变化做出对应的决策。

比如一个分布式存储系统,有一个中央控制节点负责存储的分配,当有新的存储进来时我们要根据现在集群当前的状态分配存储节点。这时我们就需要动态感知到集群目前的状态。

还有,比如一个分布式的SOA架构中,服务是一个集群提供的,当消费者访问某个服务时,就需要采用某种机制发现现在有哪些节点可以提供该服务(这也称之为服务发现,比如Alibaba开源的SOA框架Dubbo就采用了Zookeeper作为服务发现的底层机制)。还有开源的Kafka队列就采用了Zookeeper作为Cosnumer的上下线管理。


架构师成长录


ZooKeeper向Client(s)提供高可用的{键、值}对的读/写操作,高可用实现原理是通过将数据同时复制到多个节点,让Client可从任一节点读取。而ZooKeeper设计的关键是遵循了这样一个规则(observation),即每个状态改变都是前一状态的增量;因此,它对状态改变的顺序存在一种固有依赖。ZooKeeper原子广播协议就是这样一种能确保ZooKeeper复制顺序的协议,同时它也能处理leader选举和leader失效后时的节点恢复。ZooKeeper原子广播协议英文全称,Zookeeper Atomic Broadcast (ZAB) protocol,也即本文主题。

定义

leader和followers --在ZooKeeper集群中,同一时刻,只能有一个节点担任leader, 剩下的为follower。leader负责接收来自Client(s)的所用状态变更,它在自己保存的同时,也会复制到其他的follower(s)。不过,对于所有读请求,则是被同时负载均衡到leader和follower(s)。

transactions -- 事务,即Client状态变更, 它(们)会由leader传播到它的follower(s):

  • ‘e’ -- leader的epoch。epoch是由普通节点变为leader时,生成的一个整数。它应该大于任何先前leader的epoch;
  • ‘c’ -- 一个由leader生成的序数,从0开始,向上增加。它和epoch一起被用作对不断到来的Client(s)状态改变/事务进行排序;
  • ‘F.history’ -- follower的history队列。用于确保到达事务,按照它们到达的先后顺序被提交;
  • outstanding transactions -- F.history中序号小于当前COMMIT序号的事务集合。
ZAB要求

1. 复制保证

  • 可靠递送-- 如果一个事务M被一个服务器提交,它最后也会被所有服务器提交。
  • 绝对顺序-- 如果一个服务器提交的事务A先于事务B, 那么对于所有服务器,A都将先于B被提交。
  • 因果顺序(Causal Order)-- 如果事务B发送的时间,是在B的发送者提交事务A之后,A必须是排在B之前。如果在发送B之后,某个发送者发出C ,那么C必须排在B之后。

2. 只要达到法定数量(quorum)/大多数节点是正常的,事务就会被复制。

3. 在事务复制期间,因down机错过的失败节点,恢复运行时应能再次获得。

ZAB 实现

Client(s)可以从任何ZooKeeper节点发起读操作。然而,它(们)对任何ZooKeeper节点执行写操作时,状态变更会被先转发到leader节点。

ZooKeeper使用一种two-phase-commit协议的变体,将复制事务到follower(s)。当leader接收到来自某个Client的状态更新时,它用序数c和leader epoch e(见前面定义)生成一个事务,并将其发送给所有follower(s)。

follower接收后,会将事务添加到它的history队列中,并向leader回送ACK。当leader收到法定数量(quorum)的ACK时,它就会发出事务quorum提交。接收到提交的follower(s)就会提交该事务,除非c值大于它history队列里的所用序号。这时,它会先等待接收先前事务(outstanding transaction(s))的提交操作,然后再执行该提交。

一旦leader崩溃,节点间会执行一个recovery协议,以确保以下两点:

  • 恢复正常服务之前,节点间对共同状态的一致性达成共识;
  • 找出一个新leader来广播状态更新。一个节点要行使leader角色,获得法定数量(quorum)的节点支持也是必须的。现实中,由于存在节点的崩溃、恢复往复;一段时间里,可能出现多位leader的更迭,甚至是同一节点多次成为leader的情形。

节点的生命周期:每个节点要么一次执行这个协议的一个完整循环;要么循环被突然中断,回到Phase 0, 再开始一个新的循环。

  • Phase 0 -- leader选举
  • Phase 1 -- 发现
  • Phase 2 -- 同步
  • Phase 3 -- 广播

注:Phase 1和Phase 2,对于确保所有节点上状态的一致性很重要,特别是在节点从崩溃恢复时。

Phase 0 -- leader选举

节点在该阶段运行初始化,状态为election。leader选举协议不必多特别,只要可结束、高概率,能选出一个可用节点,选举节点数达到法定数量(quorum)就行。leader选举算法结束后,节点会将它的选举结果保存到本地内存。

大致为:如果节点p投票给p0, 那么p0就称为p的预期leader;如果节点投票给它自己,它的状态应设为leading,否则就设为following。顺便提一下,只有到达Phase 3的开始,这里选出的预期leader才可能变成真正的leader,并成为主处理节点。

Phase 1 -- 发现

在这个阶段,follower(s)和它们的预期leader保持通讯,以便leader能够收集有关follower(s)最近接受的事务信息。这个阶段的目的,是为了在法定数量(quorum)节点内,发现尽可能多的已接受事务更新序号,以便创建一个新的epoch,以防先前的leader再提交新的事务。

理论上,具有法定人数(quorum)数量的follower(s)都拥有前任leader所有已接受状态变更的信息,于是在当前法定节点数(quorum)中,至少有一个follower,在它的history队列中拥有前任leader所有已接受的状态变更。这就意味着,这位新leader同样可以获得这些信息,具体算法如下:

Phase 2 -- 同步

同步阶段对该协议的发现阶段做出总结,即leader将用发现阶段获得的变更历史,对集群节点进行同步操作。leader会和follower(s)进行通信,并从自己的history队列里发出事务。如果follower(s)的history滞后于leader,follower(s)就会回复ACK; 当leader看到来自法定节点数(quorum)的ACK,它就会发出提交信息给它们。此时,leader角色真正成立,不再是预期leader了。算法如下:

Phase 3 -- 广播

现在开始,如果没有节点发生崩溃,它们将永远呆在该阶段,收到ZooKeeper Client发出的写请求,就执行事务广播。算法如下:

注:对于失败检测,ZAB采用的是在leader和follower(s)间周期性的发送心跳(heartbeat)信息。如果leader在规定时间内,没有收到法定数量(quorum)节点的心跳,它就会放弃领导权,并转到选举状态,Phase 0;而如果follower超时未收到来自leader的心跳(heartbeat)也会转入leader选举阶段。


启迪云Tuscloud


zookeeper意思就是动物园管理员,为什么这么起名字呢?因为世面上的大数据框架比如hadoop,spark等,它们的图标都是动物,而zppkeeper可以管理这些大数据框架,所以起这个名字意思就是把动物们管理起来。哈哈,这是我的个人见解。。。


分享到:


相關文章: