最近的项目中使用到了Zookeeper、Kafka以及Storm。仔细研究了一下,以为这几个开源项目对于搞分布式的人来讲是很是有用的,因此想把本身的一点心得体会总结一下,但愿能对你们有所帮助。html
首先从Zookeeper开始。这一节主要是介绍一下Zookeeper的背景和架构node
zookeeper是一个开源分布式的服务,它提供了分布式协做,分布式同步,配置管理等功能. 它实现的功能与google的chubby基本一致。apache
Zookeeper的官方文档对它的设计实现有很详细的描述,下面咱们来简单介绍一下。session
一. Zookeeper的设计目标:数据结构
1. Simple。 ZooKeeper的命名空间组织结构相似文件系统,分布式系统能够基于它进行协做。Zookeeper中的每个节点都是一个znode,它相似于文件系统中的文件或文件夹。通用的文件系统通常都是设计用来存储数据,而Zookeeper的数据都是保存在memory中的,这也意味这ZooKeeper可以有很高的throughput和很低的延迟。架构
ZooKeeper的实现主要考虑的是高性能、高可用性以及严格的顺序访问。 高性能意味着它能够被用在大型的分布式系统中;高可用性是指使用ZooKeeper集群可以避免单点故障;严格的顺序意味着ZooKeeper的客户端能够实现复杂的同步功能。分布式
2. replicated。像不少分布式系统同样,ZooKeeper的数据会被拷贝到一个集群中的多台机器上,这些机器组成一个ZooKeeper集群,以下图所示:函数
组成ZooKeeper集群服务的Server都要获知彼此的存在。它们在内存中保存了当前ZooKeeper服务数据的最新镜像,同时每隔一段时间会持久化保存这些镜像数据以及transaction日志。这些数据能够被用来恢复ZooKeeper服务。只要大部分的ZooKeeper Server都正常,ZooKeeper服务就是可用的。oop
每一个客户端都只会链接到一个ZooKeeper Server,客户端维护了一个跟Server的TCP链接,能够经过这个链接来发送请求、获取数据、获取监听事件以及发送心跳信息。若是TCP链接断掉,客户端会尝试链接到其它Server。性能
3. Ordered。ZooKeeper为每一次update都关联一个number,它反映了全部ZooKeeper transactions的顺序。之后的操做能够基于该顺序实现更高层次的抽象,好比分布式同步锁等。
4. Fast。ZooKeeper在以读操做为主的场景中尤为快。ZooKeeper应用能够运行在成百上千台机器中,当读写操做比为10:1时它表现的最好。
二. ZooKeeper的数据模型和层次式的命名空间。
ZooKeeper提供的命名空间很像一个标准的文件系统,以下图所示,它的名字是一系列由"/"分隔的路径。ZooKeeper命名空间中的每个节点都由一个路径指定。
三. ZooKeeper节点以及ephemeral节点
同文件系统不一样的是,每个ZooKeeper的节点都既能够存储数据也能够含有子节点。普通文件系统中,只有文件夹能够有子文件或子目录,文件只能用来存储数据。因此这里ZooKeeper就好像是文件系统容许一个文件能够有文件夹的功能。ZooKeeper是被设计用来存储一些协做数据的,好比说状态信息、配置信息、位置信息等,因此一般每一个节点存储的数据量都是很是小的(范围在byte和kilobyte之间)。咱们用术语znode代表咱们讨论的是ZooKeeper的数据节点。
znode维护了一个stat数据结构,它包含了如下信息:
当这个节点的内容或是子节点有改动时,对应的Stat中存储的值会被更新. ZooKeeper的客户端获取该znode的数据时,它也同时会得到这些stat信息。
每一个命名空间对应的znode节点存储的数据的读和写都是原子操做,也即读的话会获取当前存储的全部数据,写的话会用新数据覆盖旧数据。每一个znode都有一个ACL(Access Control List)来限制谁能够对该znode作哪些操做。
ephemeral znode是ZooKeeper中的一个重要概念,这是一中特殊的znode,只要建立它的那个session一直存在,这个znode就一直存在,一旦这个session结束了,这个znode就会被删除。这对于分布式系统各个组件之间相互协做是很是有用的,能够经过注册ephemeral 节点来标识当前各个组件的运行状态(live or dead)。
ZooKeeper中存在下述的3种类型znode:
四. ZooKeeper的Watch
ZooKeeper中有Watch的概念, Zookeeper Watch 定义以下:
“A watch event is one-time trigger, sent to the client that set the watch, which occurs when the data for which the watch was set changes.”
Watch是由ZooKeeper的client在进行操做时设置的,全部的读操做(getData(), getChildren(), and exists())均可以选择设置watch。在我看来,watch能够理解为一个分布式的回调,当client关心的znode发生变化时,zookeeper将会把消息传回到client,并致使client的消息处理函数获得调用. 后面咱们会详细介绍ZooKeeper的Watch的实现机制。
五. ZooKeeper的保证
ZooKeeper很是快而且很是简单,因为它的目标是成为构建复杂系统的基石(好比说同步系统),它提供了一系列的保证,它们是:
1. 顺序的一致性。 一个Client所发送的全部更新的执行顺序跟它们的发送顺序是一致的。
2. 原子性。更新操做要么成功要么失败,不存在部分红功的状况。
3. 单一系统镜像。在一个ZooKeeper集群中,一个Client不论连接到哪一个Server上,它看到的ZooKeeper系统的状态/视图应该是相同的。
4. 可靠性。 一旦一个更新操做执行成功,这个更改就会一直存在直到有一个client又对它进行了更改/覆盖。
5. 时效性。在必定的时间限制范围内,确保全部client看到的ZooKeeper系统的数据是最新的。
但愿看完这一章以后,你们会对ZooKeeper有一个基础的印象,后面的章节会详细介绍ZooKeeper中设计和实现。