分布式系统和应用,不只能提供更强的计算能力,还能为咱们提供更好的容灾性和扩展性。
算法
ZooKeeper是Google的Chubby项目的开源实现,它曾经做为Hadoop的子项目,在大数据领域获得普遍应用数据库
ZooKeeper以Fast Paxos算法为基础,同时为了解决活锁问题,对Fast Paxos算法进行了优化,所以也能够普遍用于大数据以外的其余分布式系统,为大型分布式系统提供可靠的协做处理功能。缓存
Apache ZooKeeper旨在减轻构建健壮的分布式系统的任务。ZooKeeper基于分布式计算的核心概念而设计,主要目的是给开发人员提供一套容易理解和开发的接口,从而简化分布式系统构建的任务。服务器
ZooKeeper的设计保证了其健壮性,这就使得应用开发人员能够更多关注应用自己的逻辑,而不是协同工做上。ZooKeeper从文件系统API网络
ZooKeeper从文件系统API获得启发,提供一组简单的API,使得开发人员能够实现通用的协做任务,包括选举主节点、管理组内成员关系、管理元数据等。多线程
ZooKeeper包括一个应用开发库(主要提供Java和C两种语言的API)和一个用Java实现的服务组件。ZooKeeper的服务组件运行在一组专用服务器之上,实现的服务组件。架构
当你决定使用ZooKeeper来设计应用时,最好将应用数据和协同数据独立开。整个ZooKeeper服务所管理的就是后者(协同数据,或称元数据)并发
它能够在分布式系统中协做多个任务。框架
一个协做任务是指一个包含多个进程的任务。这个任务能够是为了协做或者是为了管理竞争。异步
协做意味着多个进程须要一同处理某些事情,一些进程采起某些行动使得其余进程能够继续工做
Apache HBase
HBase是一个一般与Hadoop一块儿使用的数据存储仓库。在HBase中,ZooKeeper用于选举一个集群内的主节点,以便跟踪可用的服务器,并保存集群的元数据。
Apache Kafka
Kafka是一个基于发布-订阅(pub-sub)模型的消息系统。其中ZooKeeper用于检测崩溃,实现主题(topic)的发现,并保持主题的生产和消费状态。
Apache Solr
Solr是一个企业级的搜索平台。Solr的分布式版本命名为SolrCloud,它使用ZooKeeper来存储集群的元数据,并协做更新这些元数据。
Yahoo!Fetching Service
Yahoo!Fetching Service是爬虫实现的一部分,经过缓存内容的方式高效地获取网页信息,同时确保知足网页服务器的管理规则(好比robots.txt文件)。该服务采用ZooKeeper实现主节点选举、崩溃检测和元数据存储。
Facebook Messages
Facebook推出的这个应用(http://on.fb.me/1a7uViK )集成了email、短信、Facebook聊天和Facebook收件箱等通讯通道。该应用将ZooKeeper做为控制器,用来实现数据分片、故障恢复和服务发现等功能。
Zookeep的客户端API功能强大,其中包括:
ZooKeeper以前的其余一些系统采用分布式锁管理器或者分布式数据库来实现协做。实际上,ZooKeeper也从这些系统中借鉴了不少概念。
可是,ZooKeeper的设计更专一于任务协做,并不提供任何锁的接口或通用存储数据接口。同时,ZooKeeper没有给开发人员强加任何特殊的同步原语,使用起来很是灵活。
ZooKeeper可让开发人员更专一于其应用自己的逻辑而不是神秘的分布式系统概念
整个ZooKeeper的服务器集群管理着应用协做的关键数据。ZooKeeper不适合用做海量数据存储。最佳实践仍是应该将应用数据和协同数据独立开
ZooKeeper中实现了一组核心操做,经过这些能够实现不少常见分布式应用的任务。ZooKeeper并无为你实现这些任务(应用服务采用主节点方式或进程响应跟踪方式?),也没有为应用实现主节点选举,或者进程存活与否的跟踪的功能,可是,ZooKeeper提供了实现这些任务的工具,对于实现什么样的协同任务,由开发人员本身决定。
分布式系统是同时跨越多个物理主机,独立运行的多个软件组件所组成的系统
采用分布式去设计系统有不少缘由,
分布式系统可以利用多处理器的运算能力来运行组件,好比并行复制任务。
一个系统也许因为战略缘由,须要分布在不一样地点,好比一个应用由多个不一样地点的服务器提供服务。
使用一个独立的协调组件有几个重要的好处:
首先,咱们能够独立地设计和实现该组件,这样独立的组件能够跨多个应用共享。
其次,系统架构师能够简化协做方面的工做,这些并非琐碎的小事
最后,系统能够独立地运行和协做这些组件,独立这样的组件,也简化了生产环境中解决实际问题的任务。
软件组件以操做系统的进程方式运行,不少时候还涉及多线程的执行。所以ZooKeeper的服务端和客户端也是以进程的方式运行,一个单独的物理主机(不管是一个独立主机仍是一个虚拟环境中的操做系统)上运行一个单独的应用进程,尽管进程可能采用多线程运行的方式,以便利用现代处理器的多核(multicore)处理能力。
分布式系统中的进程通讯有两种选择:直接经过网络进行信息交换,或读写某些共享存储。
ZooKeeper使用共享存储模型来实现应用间的协做和同步原语。
对于共享存储自己,又须要在进程和存储间进行网络通讯。咱们强调网络通讯的重要性,由于它是分布式系统中并发设计的基础。
在真实的系统中,咱们须要特别注意如下问题:
关于这些问题的一个重要结果是,在实际状况中,咱们很难判断一个进程是崩溃了仍是某些因素致使了延时
ZooKeeper的精确设计简化了这些问题的处理,ZooKeeper并非彻底消除这些问题,而是将这些问题在应用服务层面上彻底透明化,使得这些问题更容易处理。
ZooKeeper实现了重要的分布式计算问题的解决方案,直观为开发人员提供某种程度上实现的封装,至少这是咱们一直但愿的。
通常在这种架构中,主节点进程负责跟踪从节点状态和任务的有效性,并分配任务到从节点。
要实现主-从模式的系统,咱们必须解决如下三个关键问题:
为了处理这些问题,
以前的主节点出现问题时,系统须要可靠地选举一个新的主节点,
判断哪些从节点有效,并断定一个从节点的状态相对于系统其余部分是否失效。
主节点失效时,咱们须要有一个备份主节点(backup master)。
备份主节点接管主要主节点的角色,进行故障转移
状态恢复:新的主要主节点须要可以恢复到旧的主要主节点崩溃时的状态
对于主节点状态的可恢复性,咱们不能依靠从已经崩溃的主节点来获取这些信息,而须要从其余地方获取,也就是经过ZooKeeper来获取。
错误的假设:假如主节点有效,备份主节点却认为主节点已经崩溃
例如主节点负载很高,致使消息任意延迟,备份主节点将会接管成为主节点的角色,执行全部必需的程序,最终可能以主节点的角色开始执行,成为第二个主要主节点。
更糟的是,若是一些从节点没法与主要主节点通讯,如因为网络分区(network partition)错误致使,这些从节点可能会中止与主要主节点的通讯,而与第二个主要主节点创建主-从关系。针对这个场景中致使的问题,咱们通常称之为脑裂(split-brain):系统中两个或者多个部分开始独立工做,致使总体行为不一致性。咱们须要找出一种方法来处理主节点失效的状况,关键是咱们须要避免发生脑裂的状况。
从节点失效
若是从节点崩溃了,全部已派发给这个从节点且还没有完成的任务须要从新派发。
首要需求是让主节点具备检测从节点的崩溃的能力。
一个从节点崩溃时,从节点也许执行了部分任务,也许所有执行完,但没有报告结果。若是整个运算过程产生了其余做用,咱们还有必要执行某些恢复过程来清除以前的状态。
若是一个从节点与主节点的网络链接断开,好比网络分区(network partition)致使,从新分配一个任务可能会致使两个从节点执行相同的任务。
若是一个任务容许屡次执行,咱们在进行任务再分配时能够不用验证第一个从节点是否完成了该任务。
若是一个任务不容许,那么咱们的应用须要适应多个从节点执行相同任务的可能性。
通讯故障致使的另外一个重要问题是对锁等同步原语的影响。
首先,客户端能够告诉ZooKeeper某些数据的状态是临时状态(ephemeral);
其次,同时ZooKeeper须要客户端定时发送是否存活的通知,若是一个客户端未能及时发送通知,那么全部从属于这个客户端的临时状态的数据将所有被删除。
经过这两个机制,在崩溃或通讯故障发生时,咱们就能够预防客户端独立运行而发生的应用宕机。
理想的方式是,以上每个任务都须要经过原语的方式暴露给应用,对开发者彻底隐藏实现细节。
ZooKeeper提供了实现这些原语的关键机制,所以,开发者能够经过这些实现一个最适合他们需求、更加关注应用逻辑的分布式应用。
配置信息也许发生了变化,咱们能够中止全部进程,从新分发配置信息的文件,而后从新启动,可是从新配置就会延长应用的停机时间。
组成员关系的问题,当负载变化时,咱们但愿增长或减小新机器和进程。
当你在开发分布式应用时,你就会遇到真正困难的问题,你就不得不面对故障,如崩溃、通讯故障等各类状况。这些问题会在任何可能的点忽然出现,甚至没法列举须要处理的全部的状况。
拜占庭将军问题(Byzantine Faults)
在独立主机上运行的应用与分布式应用发生的故障存在显著的区别:
在分布式应用中,可能会发生局部故障,
当独立主机崩溃,这个主机上运行的全部进程都会失败,
若是是独立主机上运行多个进程,一个进程执行的失败,其余进程能够经过操做系统得到这个故障,操做系统提供了健壮的多进程消息通讯的保障。
在分布式环境中这一切发生了改变:若是一个主机或进程发生故障,其余主机继续运行,并会接管发生故障的进程,为了可以处理故障进程,这些仍在运行的进程必须可以检测到这个故障,不管是消息丢失或发生了时间偏移。
FLP(由其做者命名:Fischer,Lynch,Patterson),这个结论证实了在异步通讯的分布式系统中,进程崩溃,全部进程可能没法在这个比特位的配置上达成一致 [1] 。
相似的定律称为CAP,表示一致性(Consistency)、可用性(Availability)和分区容错性(Partitiontolerance),该定律指出,当设计一个分布式系统时,咱们但愿这三种属性所有知足,但没有系统能够同时知足这三种属性 [2] 。
所以ZooKeeper的设计尽量知足一致性和可用性,固然,在发生网络分区时ZooKeeper也提供了只读能力。
所以,咱们没法拥有一个理想的故障容错的、分布式的、真实环境存在的系统来处理可能发生的全部问题。但咱们仍是能够争取一个稍微不那么宏伟的目标。
首先,咱们只好对咱们的假设或目标适当放松,例如,咱们能够假设时钟在某种范围内是同步的,咱们也能够牺牲一些网络分区容错的能力并认为其一直是一致的,当一个进程运行中,也许屡次因没法肯定系统中的状态而被认为已经发生故障。虽然这些是一些折中方案,而这些折中方案容许咱们创建一些印象很是深入的分布式系统。
不得不指出,完美的解决方案是不存在的,咱们重申ZooKeeper没法解决分布式应用开发者面对的全部问题,而是为开发者提供了一个优雅的框架来处理这些问题。
多年以来,ZooKeeper在分布式计算领域进行了大量的工做。Paxos算法 [1] 和虚拟同步技术(virtual synchrony) [2]给ZooKeeper的设计带来了很大影响,经过这些技术能够无缝地处理所发生的某些变化或状况,并提供给开发者一个框架,来应对没法自动处理的某些状况。
能够很容易地部署ZooKeeper集群,轻松经过这个集群开发应用,但实际上,在使用ZooKeeper时,有些状况ZooKeeper自身没法进行决策而是须要开发者本身作出决策,有些开发者并不彻底了解这些。