1.zookeeper是什么?
zookeeper是应用于集群或者节点组中的一种分布式协调服务,管理集群中的各个节点,并通过稳健的同步技术维护共享数据。
2.zookeeper基本概念介绍
2.1 zookeeper中的角色
(a)leader:负责进行投票的发起和决议,更新系统状态。
(b)follower:用于接受客户端请求并想客户端返回结果,在选主过程中参与投票。
(c)observer可以接受客户端连接,将写请求转发给leader,但observer不参加投票过程,只同步leader的状态,observer的目的是为了扩展系统,提高读取速度。
2.2 zookeeper中的节点
Znode被分为持久(persistent)节点,顺序(sequential)节点和临时(ephemeral)节点。
(a)持久节点:zookeeper与在创建该特定znode的客户端断开连接后,持久节点仍然存在。
(b)临时节点:客户端活跃时,临时节点就是有效的。当客户端与ZooKeeper集合断开连接时,临时节点会自动删除。
(c)顺序节点: 顺序节点可以是持久的或临时的。
3.zookeeper工作原理
3.1 zookeeper工作原理
zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了,进入了广播模式。每个Server在工作过程中有三种状态:
(a)LOOKING:当前Server不知道leader是谁,正在搜寻。
(b)LEADING:当前Server即为选举出来的leader。
(c)FOLLOWING:leader已经选举出来,当前Server与之同步。
3.2 zookeeper选主流程
当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。
(a)基于basic paxos的选主流程:
- 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
- 选举线程首先向所有Server发起一次询问(包括自己);
- 选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
- 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
- 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数,设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。
(b)基于fast paxos的选主流程:在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和 zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。
3.3 zookeeper同步流程
选完Leader以后,zk就进入状态同步过程。
- Leader等待server连接;
- Follower连接leader,将最大的zxid发送给leader;
- Leader根据follower的zxid确定同步点;
- 完成同步后通知follower 已经成为uptodate状态;
- Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。
3.4 zookeeper读写流程
一旦ZooKeeper集合启动,它将等待客户端连接。客户端将连接到ZooKeeper集合中的一个节点。它可以是leader或follower节点。一旦客户端被连接,节点将向特定客户端分配会话ID并向该客户端发送确认。如果客户端没有收到确认,它将尝试连接ZooKeeper集合中的另一个节点。 一旦连接到节点,客户端将以有规律的间隔向节点发送心跳,以确保连接不会丢失。
-
如果客户端想要读取特定的znode,它将会向具有znode路径的节点发送读取请求,并且节点通过从其自己的数据库获取来返回所请求的znode。为此,在ZooKeeper集合中读取速度很快。
-
如果客户端想要将数据存储在ZooKeeper集合中,则会将znode路径和数据发送到服务器。连接的服务器将该请求转发给leader,然后leader将向所有的follower重新发出写入请求。如果只有大部分节点成功响应,而写入请求成功,则成功返回代码将被发送到客户端。 否则,写入请求失败。绝大多数节点被称为 Quorum 。
组件 | 描述 |
写入 | 写入过程由leader节点处理。leader将写入请求转发到所有其它follower,并等待follower的回复。如果一半的follower回复,则写入过程完成。 |
读取 | 读取由特定连接的follower/observer在内部执行,因此不需要与集群进行交互。 |
复制数据库 | 它用于在zookeeper中存储数据。每个节点都有自己的数据库,每个节点在一致性的帮助下每次都有相同的数据。 |
Leader | Leader是负责处理写入请求的节点 |
Follower | follower从客户端接收写入请求,并将它们转发到leader 节点 |
请求处理器 | 只存在于leader节点。它管理来自follower节点的写入请求 |
原子广播 | 负责广播从leader节点到follower节点的变化。 |
3.5 zookeeper的负载均衡算法有哪些?
- 轮询:将请求按照顺序分发到每台服务器上,当其中一台服务器出现故障时,就不参加下一次的轮询,直至恢复正常。
- 比率:给每台服务器分配一个加权值为比例,根据比例来分配请求。
- 优先权:给所有的服务器分组,然后给每个组设置优先权,所有的请求先分配到优先权最高的服务器组,当该组出现故障后,请求再分配都次级优先权高的服务器组。
- 最少连接数:将请求分配到连接数最少的服务器
- 最快响应时间:将请求分配到响应时间最快的服务器
4.zookeeper的作用
(a)命名服务:zookeeper内部同一目录下只有唯一一个文件名,所以创建一个目录,既有唯一的path。
(b)配置管理:如果应用程序部署在多台机器上,那么应用程序的相关配置就需要在这些机器上逐个的去单独配置。但是如果把这些配置放到zookeeper中的某个节点中,然后让这些应用程序监听这个节点,当节点中的配置信息发生变化时,每个应用程序就会收到zookeeper的通知,然后将最新的配置信息更新到系统中。
(c)集群管理:集群管理涉及两个方面 是否有机器加入或者退出,选举master。对于机器加入或者退出,因为所有的机器在zookeeper中的某个目录(我们假设为FatherNode)下都会创建一个临时子节点(ClientNode1,ClientNode2。。。),然后监听父目录FatherNode下所有子节点的变化信息,一旦机器挂掉,则与zookeeper断开连接,那么该机器对应的临时子节点也会被删除,同时其他兄弟节点都会收到通知:该机器挂掉,退出集群了。对于新机器加入,也是类似原理。对于选举master,当原来的master挂掉后,需要从其他节点中重新选举出一个新的master,选举的方式可以是 每次选取编号最小的机器作为master就好,当然也可以通过其他方式。
(d)分布式锁:使用zookeeper提供分布式锁有两种 保持独占和控制时序。对于保持独占,就是把zookeeper中的一个znode当做一把锁,比如所有的客户端都去创建/lock_updateGoods节点,创建成功的客户端就获取了锁。当释放锁时,就删除/lock_upateGoods节点就行。对于控制时序, /lock_upateGoods目录已经存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除该临时目录节点。
(e)队列管理:有两种类型队列 ,一种是当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。对于这一种队列,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。另外一种是按照FIFO的方式入队和出队,入队出队根据编号。
5.思考几个问题
5.1 为什么zookeeper集群的数目,一般为奇数个?
答:Leader选举算法采用了Paxos协议,而该协议的核心思想是:超过半数的server写成功,即表示写成功。比如三台服务器和四台服务器都是最多只能有一台服务器挂掉,它们的容灾能力都是一样的,所以为了节省服务器资源,一般我们采用奇数个数,作为服务器部署个数。