Zookeeper知识总结

Zookeeper简介

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务框架,是Google的Chubby一个开源的实现、Hadoop和Hbase的重要组件。ZooKeeper的主要功能是为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

Zookeeper的设计思想

Zookeeper是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理一个集群中所有角色和节点都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应,从而实现集群中类似的Master/Slave管理模式。

在这里插入图片描述

Zookeeper的特点

  1. Zookeeper集群中有主从两种角色,由一个领导者(Leader),多个跟随者(Follower)组成。
  2. Zookeeper集群中只要有半数以上节点存活,集群就能正常服务。
  3. Zookeeper具有全局数据一致,每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
  4. 在Zookeeper中,更新请求顺序进行,来自同一个Client的更新请求按其发送顺序依次执行。
  5. 数据更新原子性,一次数据更新要么成功,要么失败。
  6. 实时性,在一定时间范围内,Client能读到最新数据。

Zookeeper中的数据结构

ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode。每一个ZNode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识。
在这里插入图片描述

Zookeeper的应用场景

Zookeeper可以提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。

统一命名服务

在分布式环境下,经常需要对应用/服务进行统一命名,便于识别不同服务。类似于域名与ip之间对应关系,ip不容易记住,而域名容易记住。通过Zookeeper提供的统一命名服务,用户可以使用服务名称来获取资源或服务的地址,提供者等信息。

在这里插入图片描述

统一配置管理

分布式环境下,配置文件管理和同步是一个常见问题。一个集群中,所有节点的配置信息是一致的,比如Hadoop集群。对配置文件修改后,希望能够快速同步到各个节点上。而这样的全局统一配置管理可交由ZooKeeper实现。
可将配置信息写入ZooKeeper上的一个Znode。ZooKeeper集群中的各个节点监听这个Znode。一旦Znode中的数据被修改,ZooKeeper将通知集群中的各个节点,修改配置,实现全局的配置文件更新。

在这里插入图片描述

统一集群管理

分布式环境中,为了能够根据节点实时状态做出一些调整,常常需要掌握每个节点的实时状态。ZooKeeper可以实现分布式环境下集群中各节点的状态监控和管理。
ZooKeeper将集群中的节点信息写入一个Znode。监听这个Znode可获取它的实时状态变化。在HBase中,内置了一个ZooKeeper,Master的状态监控与选举使用的就是这个HBase自己内置的ZooKeeper。

在这里插入图片描述

服务器节点动态上下线

分布式环境中经常会遇到节点的增删,通过Zookeeper,客户端能实时洞察到服务器上下线的变化。

在这里插入图片描述

软负载均衡

Zookeeper也可以提供Nginx的负载均衡服务。Zookeeper记下每台服务器的访问数,将最新的客户端请求转发给被访问数最少的服务器去处理。
在这里插入图片描述

Zookeeper核心算法Fast Paxos

ZooKeeper作为一个分布式应用程序协调服务框架,其核心是在分布式系统中进行通信,而保证通信的可靠性及正确性,是非常重要的,Zookeeper的通信,是以Fast Paxos算法为基础的,而Fast Paxos算法是在Paxos算法的基础上改进而来的,所以,如果想对ZooKeeper的工作机制有深入的了解,就必须掌握Paxos算法及Fast Paxos算法的原理。

Paxos算法

Paxos算法一种基于消息传递且具有高度容错特性的一致性算法。分布式系统中的节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。基于消息传递通信模型的分布式系统,不可避免的会发生以下错误:进程可能会慢、被杀死或者重启,消息可能会延迟、丢失、重复,在基础 Paxos 场景中,先不考虑可能出现消息篡改即拜占庭错误的情况。Paxos 算法解决的问题是在一个可能发生上述异常的分布式系统中如何就某个消息(决议)达成一致,保证不论发生以上任何异常,都不会破坏决议的一致性。

Paxos算法中节点的三种角色

Paxos算法中的参与者主要分为Proposer,Acceptor,Learner三个角色,每个参与者(节点)可兼任多个角色。

Proposer:提出者,提出提案,提案信息包括提案编号和提议的value。

Acceptor:表决者,收到提案后可以决定是否accept接受提案。

Learner:不参加提案的表决过程,当提案表决通过后执行提案内容。

Paxos算法的三个阶段

一个完整的Paxos算法流程分为三个阶段:

Prepare阶段

Proposer向Acceptors发出Prepare(准备)请求,Acceptors针对收到的Prepare请求进行Promise承诺,这一阶段是为了确认集群中有多少个Acceptors表决者可以参与表决。

Accept阶段

Proposer收到多数(这里的多数是指半数以上,所以集群最好有奇数个节点)Acceptors承诺的Promise后,Proposer向Acceptors发出Propose(提议)请求,Acceptors针对收到的Propose请求进行Accept处理。

Learn阶段:

当Proposer提出的Propose提议被Acceptors通过后,Proposer会将形成的决议发送给所有Learners。

在这里插入图片描述

Paxos算法的详细流程

Paxos算法流程中的每条消息从被Proposer提出到被Learner使用会经过一下流程:

  1. Prepare: Proposer生成全局唯一且递增的Proposal ID (可使用时间戳加Server ID),向所有Acceptors发送Prepare请求,这里无需携带提案内容,只携带Proposal ID即可。
  2. Promise: Acceptors收到Prepare请求后,做出“两个承诺,一个应答”。
    两个承诺:
    a. 不再接受Proposal ID小于等于(注意:这里是<= )当前请求的Prepare请求。
    b. 不再接受Proposal ID小于(注意:这里是< )当前请求的Propose请求。
    一个应答:
    c. 不违背以前做出的承诺下,回复已经确认过的提案中Proposal ID最大的那个提案的Value和Proposal ID,没有则返回空值。
  3. Propose: Proposer 收到多数Acceptors的Promise应答后,从应答中选择Proposal ID最大的提案的Value,作为本次要发起的提案。如果所有应答的提案Value均为空值,则可以自己随意决定提案Value。然后携带当前Proposal ID,向所有Acceptors发送Propose请求。
  4. Accept: Acceptor收到Propose请求后,在不违背自己之前做出的承诺下,接受并持久化当前Proposal ID和提案Value。
  5. Learn: Proposer收到多数Acceptors的Accept后,决议形成,将形成的决议发送给所有Learners。

下面我们针对上述描述做三种情况的推演举例:为了简化流程,我们这里不设置Learner。

Paxos算法举例

这里举一些使用Paxos算法的表决过程,分析一下Paxos算法存在的弊端

案例1

只有一个Proposer的表决过程,A1是Proposer,A2-A5是Acceptors。

在这里插入图片描述

  1. A1发起1号提案的Prepare请求,等待承诺。
  2. A2-A5收到A1发来的Prepare请求后,回应Promise请求。
  3. A1在收到两份回复时就会发起提案1。
  4. A2-A5回应Accept接受。
  5. 提案1获得通过。

可以看出当只有一个Proposer时,表决过程是非常顺利的。

案例2

当有两个Proposer的表决过程,A1和A5都是Proposer,A2-A4是Acceptors。这种情况下有可能发生两个Proposer相互竞争的活锁情况,也有可能会顺利完成表决。

在这里插入图片描述

  1. A1,A5同时发起Prepare(序号分别为1,2)。
  2. A2承诺A1,A4承诺A5,A3行为成为关键。
  3. A3收到A1Prepare请求,然后承诺A1。这时A1有两个承诺,A2和A3。

到这里后有可能会发生两种情况:

情况1(正常):

  1. A3先收到A1先发起的Proposal(提案1),A2、A3接受,A1发起的Proposal(提案1)通过。
  2. 之后A3又收到A5消息,并承诺A5。
  3. A5发起Proposal(提案2),A3,A4接受。之后A1,A5同时广播决议。

情况2(活锁):

  1. A3先收到A5Prepare请求,然后承诺A5。这时A5有两个承诺,A4和A3,A1有一个承诺 A2(A3不能同时承诺两个Proposer)。
  2. A1发起Proposal(提案1),由于A1现在只有一个承诺,所以无足够响应,A1重新发起 Prepare请求,A3再次承诺A1。这时A1有两个承诺,A2和A3,A5有一个承诺A4。
  3. A5发起Proposal(提案2),由于A5现在只有一个承诺,所以无足够响应,A5重新发起 Prepare请求,A3再次承诺A5。
  4. A1因无足够响应,发起Prepare请求。
  5. A5因无足够响应,发起Prepare请求。
    。。。。。。
    产生活锁

Paxos算法总结

Paxos算法存在活锁的问题,即当有多个Proposer交错提交时,有可能互相排斥导致没有一个Proposer能提交成功

1)半数机制:集群中半数以上机器存活,集群可用。所以Zookeeper适合安装奇数台服务器。
2)Zookeeper虽然在配置文件中并没有指定Master和Slave。但是,Zookeeper工作时,是有一个节点为Leader,其他则为Follower,Leader是通过内部的选举机制临时产生的。
3)以一个简单的例子来说明整个选举的过程。
假设有五台服务器组成的Zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来看看会发生什么,如图5-8所示。

Fast Paxos算法

针对Paxos算法存在活锁的问题,Fast Paxos作了一些优化,Fast Paxos算法中新加入了Leader 这一角色,通过选举产生一个Leader来避免活锁问题。在Fast Paxos算法中,只有Leader才能提交Proposal决议。

Fast Paxos算法选举Leader过程案例

假设有五台服务器组成的Zookeeper集群,它们的ID从1-5,都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器按ID顺序依序启动。

在这里插入图片描述

  1. 服务器1启动,发起一次选举。服务器1投自己一票。此时服务器1票数一票,不够半数以上(3票),选举无法完成,服务器1状态保持为LOOKING;

  2. 服务器2启动,再发起一次选举。服务器1和2分别投自己一票并交换选票信息:此时服务器1发现服务器2的ID比自己目前投票推举的(服务器1)大,更改选票为推举服务器2。此时服务器1票数0票,服务器2票数2票,没有半数以上结果,选举无法完成,服务器1,2状态保持LOOKING

  3. 服务器3启动,发起一次选举。此时服务器1和2都会更改选票为服务器3。此次投票结果:服务器1为0票,服务器2为0票,服务器3为3票。此时服务器3的票数已经超过半数,服务器3当选Leader。服务器1,2更改状态为FOLLOWING,服务器3更改状态为LEADING;

  4. 服务器4启动,发起一次选举。此时服务器1,2,3已经不是LOOKING状态,不会更改选票信息。交换选票信息结果:服务器3为3票,服务器4为1票。此时服务器4服从多数,更改选票信息为服务器3,并更改状态为FOLLOWING;

  5. 服务器5启动,同服务器4一样,服从多数,更改选票信息为服务器3,并更改状态为FOLLOWING。

Fast Paxos算法总结

从上面的案例可以看出,Fast Paxos算法大部分机制和Paxos算法是一样的,只是加入了Leader角色避免了活锁问题。

发布了171 篇原创文章 · 获赞 150 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/eagleuniversityeye/article/details/104085173
今日推荐