duan2

导航

 

1.1ZooKeeper的使命

 

当开发人员使用ZooKeeper进行开发时,开发人员设计的那些应⽤往往可以看成成组连接到ZooKeeper服务器端的客户端,它们通过ZooKeeper的客户端API连接到ZooKeeper服务器端进行相应的操作。Zookeep的客户端API功能强大,其

中包括:

  1.  保障强一致性、有序性和持久性。
  2. 实现通用的同步原语的能力。
  3. ·在实际分布式系统中,并发往往导致不正确的行为。ZooKeeper提供了一种简单的并发处理机制。 

 

 1.1.1通过ZooKeeper构建分布式系统

  对分布式系统的定义有很多,但对于本书的目的,我们对分布式系统的定义为:分布式系统是同时跨越多个物理主机,独立运行的多个软件组件所组成的系统。我们采用分布式去设计系统有很多原因,分布式系统能够利用多处理器的运算能力来运行组件,例如并行复制任务。多个系统也许由于战略原因,需要分布在不同地点,例如多个应用由多个不同地点的服务器提供服务。

  

  分布式系统中的进程通信有两种选择:直接通过网络进行信息交换,或读写某些共享存储。ZooKeeper使用共享存储模型来实现应用间的协作和同步原语。对于共享存储本身,又需要在进程和存储间进行网络通信。我

们强调调络通信的重要性,因为它是分布式系统中并发设计的基础。

 

在真实的系统中,我们需要特别注意以下问题:

消息延迟

 

消息传输可能会发送任意延迟,例如,因为网络拥堵。这种任意延迟可能会导致不可预期的后果。例如,根据基准时钟,进程P先发送了一个消息,之后另一个进程Q发送了消息,但是进程Q的消息也许会先完成传

送。

 

处理器性能

操作系统的调度和超载也可能导致消息处理的任意延迟。当一个进程向另一个进程发送消息时,整个消息的延时时间约等于发送端消耗的时间、传输时间、接收端的处理时间的总和。如果发送或接收过程需要调度

时间进行处理,消息延时会更高

 

时钟偏移

使用时间概念的系统并不少见,比如,确定某一时间系统中发生了哪些事件。处理器时钟并不可靠,它们之间也会发生任意的偏移。因此,依赖处理器时钟也许会导致错误的决策。

 

  ZooKeeper的精确设计简化了这些问题的处理,ZooKeeper并不是完全消除这些问题,而是将这些问题在应用服务层面上完全透明化,使得这些问题更容易处理。ZooKeeper实现了重要的分布式计算问题的解决方案,直观为开发发员提供某种程度上实现的封装,至少这是我们⼀直希望的。

1.2实例:主-从应用

我们从理论上介绍了分布式系统,现在,是时候让它更具体一点了。考虑在分布式系统设计中一个得到广泛应赢的架构:一个主-从(master-worker)架构(图1-1)

 

 一般在这种架构中,主节点进程负责跟踪从节点状态和任务的有效性,并分配任务到从节点。对ZooKeeper来说,这个架构风格具有代表性,阐述了大多数流行的任务,如选举主节点,跟踪有效的从节点,维护应用元数据。

 

 

要实现主-从模式的系统,我们必须解决以下三个关键问题:

主节点崩溃

如果主节点发送错误并失效,系统将无法分配新的任务或重新分配已失败的任务。

从节点崩溃

如果从节点崩溃,已分配的任务将无法完成。

通信故障

如果主节点和从节点之间无法进行信息交换,从节点将无法得知新任务分配给它。

 

1.2.1 主节点失效

  主节点失效时,我们需要有一个备份主节点(backup master)。当主要主节点(primary master)崩溃时,备份主节点接管主要主节点的角色,进行故障转移,然而,这并不是简单开始处理进入主节点的请求。新的主要主节点需要能够恢复到旧的主要主节点崩溃时的状态。对于主节点状态的可恢复性,我们不能依靠从已经崩溃的主节点来获取这些信息,而需要从其他地⽅获取,也就是通过ZooKeeper来获取。

  状态恢复并不是唯一的重要问题。假如主节点有效,备份主节点却认为主节点已经崩溃。这种错误的假设可能发生在以下情况,例如主节点负载很高,导致消息任意延迟(关于这部分内容请参见1.1.4节),备份主节点将会接管成为主节点的角色,执行所有必需的程序,最终可能以主节点的角色开始执⾏,成为第二个主要主节点。更糟的是,如果这些从节点无法与主要主节点通信,如由于网络分区(network partition)错误导致,这些从节点可能会停止与主要主节点的通信,而与第二个主要主节点建立主-从关系。针对这个场景中导致的问题,我们一般称之为脑裂(split-brain):系统中两个或者多个部分开始独立工作,导致整体行为不一致性。我们需要找出一种放法来处理主节点失效的情况,关键是我们需要避免发生脑裂的情况

 

1.2.2 从节点失效

  客户端向主节点提交任务,之后主节点将任务派发到有效的从节点中。从节点接收到派发的任务,执行完这些任务后会向主节点报告执行状态。主节点下一步会将执行结果通知给客户端。

  如果从节点崩溃了,所有已派发给这个从节点且尚未完成的任务需要重新派发。其中首要需求是让主节点具有检测从节点的崩溃的能力。主节点必须能够检测到从节点的崩溃,并确定哪些从节点是否有效以便派发崩溃节点的任务。一个从节点崩溃时,从节点也许执行了部分任务,也许全部执行完,但没有报告结果。如果整个运算过程产生了其他作用,我们还有必要执行某些恢复过程来清除之前的状态。

 1.2.3 通信故障

  如果一个从节点与主节点的网络连接断开,如网络分区(networkpartition)导致,重新分配一个任务可能会导致两个从节点执行相同的任务。如果一个任务允许多次执行,我们在进行任务再分配时可以不用验证第一个从节点是否完成了该任务。如果一个任务不允许,那么我们的应⽤需要适应多个从节点执行相同任务的可能性。

  通信故障导致的另一个重要问题是对锁等同步原语的影响。因为节点可能崩溃,而系统也可能网络分区(network partition),锁机制也会阻止任务的继续执行。因此ZooKeeper也需要实现处理这些情况的机制。首先,客户端可以告诉ZooKeeper某些数据的状态是临时状态(ephemeral);其次,同时ZooKeeper需要客户端定时发送是否存活的通知,如果一个客户端未能及时发送通知,那么所有从属于这个客户端的临时状态的数据将全部被删除。通过这两个机制,在崩溃或通信故障发生时,我们就可以预防客户端独立运行引发的应用宕机。  

  回想一下之前讨论的内容,如果我们不能控制系统中的消息延迟,就不能确定一个客户端是崩溃还是运行缓慢,因此,当我们猜测一个客户端已经崩溃,但实际上我们也需要假设客户端仅仅是执行缓慢,其在后续还可能执行一些其他操作。

 

 

1.2.4任务总结
根据之前描述的这些,我们可以得到以下主-从架构的需求:
主节点选举
这是关键的一步,使得主节点可以给从节点分配任务。
崩溃检测
主节点必须具有检测从节点崩溃或失去连接的能力。
组成员关系管理
主节点必须具有知道哪一个从节点可以执行任务的能力。
元数据管理
主节点和从节点必须具有通过某种可靠的方式来保存分配状态和执⾏
状态的能力。

posted on 2018-05-06 18:37  duan2  阅读(186)  评论(0编辑  收藏  举报