ZooKeeper:为分布式应用提供的分布式协调服务

ZooKeeper提供一系列原语用于分布式应用构建更高层次的服务,如同步、配置维护、分组以及命名空间。

设计目标:

ZooKeeper足够简单且可复制。

 
组成ZooKeeper服务当中的服务器知道彼此之间的存在。服务器在持久存储中维护状态内存映像以及事务日志和快照。只要大多数的服务是可用的,ZooKeeper服务也是可用的。
客户端连接一台ZooKeeper服务器,维护一个TCP连接,通过它连接请求、获取响应及通知事件,并发送心跳包。如果服务器端的TCP连接断开,客户端将连接到另一个服务器。
ZooKeeper是有序的。ZooKeeper时间戳每次更新都会带一个编号用于反映ZooKeeper事务的顺序。后续操作可依据这个顺序用于实现更高层次的抽象,如同步原语。
ZooKeeper是快速的。在用于读为主的应用场景特别快速。ZooKeeper应用运行于上千台机器,在读远多于写的场景上表现最佳,通常读写比例为10:1。
 
数据模型及分层命名空间
依托于ZooKeeper的命名空间有点类似标准的文件系统。名称是由“/”分隔组成的字符串。在ZooKeeper的命名空间中每个节点是用路径标识出来的。
 
节点以及临时节点
不像标准的文件系统,在ZooKeeper命令空间中每个节点都可以有数据关联到(类似子节点)。这就好像一个文件系统,允许文件也是目录。(ZooKeeper被设计用于存储分布式数据:状态信息、配置信息、位置信息等等,通常存储在每个节点的数据是比较小的,控制在KB字节范围。)在谈论ZooKeeper数据节点的时候我们通常用术语znode来说明。
znode维护一个状态数据结构,包含数据变更版本号、ACL(Access Control List)变更以及时间戳,允许缓存验证和协调更新。每当znode的数据变化时,版本号会往上增加。每当客户机检索数据时,它也接收数据版本。
在同一个命名空间中,每个znode节点当中的数据读取和写入是原子操作。读取操作能获取到该znode节点的所有数据字节,同时写入的时候会替换掉该znode节点的所有数据。每个节点都有一个ACL用于限制谁可以做什么。
ZooKeeper还有临时节点的概念。只要创建节点的会话还处于活跃状态,那么节点还是存在的,当会话关闭时则znode节点删除。
 
条件更新和订阅
ZooKeeper支持订阅。客户端可以观察节点。当节点变化时,将会触发或移除观察。当客户端接收到报文描述这个节点变化时,监听将会被触发。如果客户端和ZooKeeper的某个服务断开连接时,客户端将会接收到一个本地通知。
 
保证
ZooKeeper是很快速和简单的。虽然它的目标是对很多复杂服务如同步机制是很基础的,但它也提供了一系列的保证,如下:
1)顺序一致性-更新将会按照客户端发送的顺序来执行
2)原子性-更新要吗全部成功或失败,没有部分结果。
3)单一系统映像-不管客户端连接的是哪个服务,它最终看到的是同样的服务视图
4)可靠性-一旦更新被执行,它会一直持久存在直到被写入
5)时间性-系统客户端的视图在一定时间内会保证最新
 
简单API
Zookeeper设计的一个目标是提供简单的编程接口,所以它只支持以下操作:创建create、删除delete、存在exists、获取数据get data、设置数据set data、获取子节点get children以及同步sync。
 
实现
下述显示ZooKeeper服务的高层次组件。除了请求处理异常外,每个组成ZooKeeper服务的服务层都有它所属每个组件的拷贝。
从数据库在整个数据树上是一个内存数据库。更新将会持久化到磁盘用于恢复,在他们应用于内存数据库时,他们会先持久化到磁盘中。
每个ZooKeeper服务器服务于客户端。客户端会确切地连接到一个服务器用于提交请求。读取请求从每个服务器的本地副本获取服务。如果是更新服务状态的请求或者是写请求的话,则会被一个一致性协议所处理。
作为一致性协议的一部分所有的从客户端发起的写请求将会转发到单个服务器,我们叫它leader。剩下的ZooKeeper服务器,我们叫follower,用于接收从leader发起的消息提议同时商定消息传递。消息传递层关注当leader失败时的替换以及followers和leaders之间的同步。
 
ZooKeeper使用了一个定制的原子消息传递层。因为消息传递层是原子的,所有ZooKeeper可以确保本地副本不会偏离。当leader接收到一个写请求时,它会计算当写操作被应用的话系统状态是什么,同时将此转换成捕获新状态的事务。
 
使用
ZooKeeper的编程接口是很简单的。通过它,你可以实现高级别的操作,如同步原语、集群管理等等。
 
性能
ZooKeeper被设计于高性能的。当读操作远远多于写操作的时候,它表现得相当高性能。因为写涉及到服务器之间的同步。(读操作远远多于写操作是分布式服务的一个典型例子。)
上图(ZooKeeper吞吐量按读写比变化)是在ZooKeeper3.2发布版的吞吐量展示图,基于双核2GHZ Xeon和2个SATA 15K RPM驱动器。一个驱动器用做专门的ZooKeeper log记录。快照将会写入到OS。写请求和读请求都是1K。"Servers"显示的是组成ZooKeeper服务的服务器机器数量。将近30台机器被用于模拟客户端。ZooKeeper被配置成leader不允许从客户端发起连接。
压力测试同样显示它的稳定性。可靠性当中的错误的存在表明一个部署是如何应对不同的错误情况。在下图当中显示的事件可以归类为一下几种:
1)单个follower的故障和恢复
2)不同follower的故障和恢复
3)leader的故障
4)2个followers的故障和恢复
5)另一个leader的故障
 
可靠性
当我们运行由7台机器组成的ZooKeeper服务,我们展示系统随着时间的推移注入错误的行为。我们运行跟以前一样的饱和压力测试,但是在这时间我们保持写操作占比在30%左右,这是我们期望的工作负载的保守比例。
在这张图里面有一些很重要的指标。首先,如果followers故障同时恢复快速的,ZooKeeper能维持在一个高吞吐量状态。但是更重要的是,这个leader选举算法对系统来说允许足够快速恢复,防止吞吐量大幅下降。在我们的观察中,ZooKeeper只花费了低于200ms用于选举出一个新leader。最后当followers恢复的时候,一旦他们启动处理请求的时候ZooKeeper能快速提升吞吐量。
 
ZooKeeper项目
ZooKeeper已经成功应用于多个工业应用。它被用于在Yahoo! Message Broker(这是一个高扩展性的发布订阅系统用于关于上千个主题的发布和数据传递)的故障快速恢复以及协调服务上。它被用于Yahoo! crawler当中的抓取服务,做为一个故障恢复的管理服务。Yahoo!的一系列广告系统也使用ZooKeeper作为可靠性服务。
 

zookeeper-开始的更多相关文章

  1. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  2. [译]ZOOKEEPER RECIPES-Leader Election

    选主 使用ZooKeeper选主的一个简单方法是,在创建znode时使用Sequence和Ephemeral标志.主要思想是,使用一个znode,比如"/election",每个客 ...

  3. zookeeper源码分析之六session机制

    zookeeper中session意味着一个物理连接,客户端连接服务器成功之后,会发送一个连接型请求,此时就会有session 产生. session由sessionTracker产生的,sessio ...

  4. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  5. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  6. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  7. zookeeper源码分析之二客户端启动

    ZooKeeper Client Library提供了丰富直观的API供用户程序使用,下面是一些常用的API: create(path, data, flags): 创建一个ZNode, path是其 ...

  8. zookeeper源码分析之一服务端启动过程

    zookeeper简介 zookeeper是为分布式应用提供分布式协作服务的开源软件.它提供了一组简单的原子操作,分布式应用可以基于这些原子操作来实现更高层次的同步服务,配置维护,组管理和命名.zoo ...

  9. zookeeper集群的搭建以及hadoop ha的相关配置

    1.环境 centos7 hadoop2.6.5 zookeeper3.4.9 jdk1.8 master作为active主机,data1作为standby备用机,三台机器均作为数据节点,yarn资源 ...

  10. 如何编译Zookeeper源码

    1. 安装Ant Ant下载地址:http://ant.apache.org/bindownload.cgi 解压即可. 2. 下载Zookeeper源码包 https://github.com/ap ...

随机推荐

  1. 开始奇妙的DP之旅

    铭记各位大佬教导,开始看一些很迷的动态规划,那就从比较典型的01背包开始吧,想想还是从比较简单的导弹拦截开始吧,说简单都是骗人的,还是看采药吧. 一.动态规划 刚听到动态规划这个东西,据HLT大佬所言 ...

  2. ashMap源码阅读与解析

    目录结构 导入语 HashMap构造方法 put()方法解析 addEntry()方法解析 get()方法解析 remove()解析 HashMap如何进行遍历 导入语 HashMap是我们最常见也是 ...

  3. mina.net 梳理

    LZ最近离职,闲着也是闲着,打算梳理下 公司做的是电商,CTO打算把2.0系统用java 语言开发,LZ目前不打算做java,所以 选择离职.离职前,在公司负责的最后一个项目 供应链系统. 系统分为 ...

  4. MAMP 环境下为 php 添加 pcntl 扩展

    前言: pcntl 介绍 pcntl 扩展可以支持 PHP 的多线程操作.(非Unix类系统不支持此模块) phpize 介绍 phpize 可以用来给 PHP 动态的添加扩展.比如编译 PHP 时忘 ...

  5. jQuery修炼心得-DOM节点的插入

    1. 内部插入append()与appendTo() append:这个操作与对指定的元素执行原生的appendChild方法,将它们添加到文档中的情况类似. appendTo:实际上,使用这个方法是 ...

  6. nodejs querystring踩坑笔记----只能用于表单提交

    API中的实例: var http = require('http'); var querystring = require('querystring'); var postData = querys ...

  7. 让Unity的Inspector面板支持字符限制(restrict)功能

    今天在优化红点组件,笔者打算将红点id由10进制改为16进制处理,就打算将红点id字段由uint类型改成string类型,用于填写16进制的字符(因为在Inspector面板里,uint/int类型字 ...

  8. <javaScript> 数组去重的方法总结(2017年)

    现在要求去重下面这个数组: const arr = [1, 2, 3, 3, 3, '0', '1', '2', '测试', '重复', '重复', NaN, NaN, false, false]; ...

  9. dubbo在企业中用得多吗?

    看了阿里的dubbo,据说是一个不错的服务框架, 不过,好像Minglisoft.technology搞研发希望各位可以指点学习 想知道其他的公司用这个框架多吗?遇到的问题能否快速解决呢?抉择中...

  10. Another kind of Fibonacce(矩阵快速幂,HDU3306)

    Another kind of Fibonacci Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...