Zookeeper概要

Zookeeper: 针对分布式应用的分布式协调服务

Zookeeper是一个针对分布式应用的分布式的, 开源的协调服务. 它对外提供了一系列建立分布式应用的原语, 可用来实现更高等级的同步服务, 配置中心服务, 分组和命名服务等. Zookeeper使用了类似文件目录的树状数据模型.
协调服务很容易出错, 比如竞争条件和死锁. Zookeeper一开始的目的就是实现一个可靠的分布式应用协调服务.

设计目标

Zookeeper是简单的

Zookeeper通过类似文件系统的可共享的分级命名空间来协调分布部署的各个进程. 这个命名空间由数据注册组成, 在Zookeeper中称为znodes. Zookeeper不像典型的文件系统, 它把数据保存在内存中, 这保证Zookeeper的高吞吐和低延迟.
Zookeeper的实现把额外的开销都放在了高性能, 高可用, 严格的顺序访问上面. 高性能意味着Zookeeper能够在大分布式系统中使用. 可靠性能够保证在单点故障的时候, 系统依旧可以使用. 严格的顺序访问意味着在客户端可以实现复杂的同步原语.

Zookeeper是可复制的

像Zookeeper协调的分布式进程那样, 它自己也旨在实现在一系列主机中进行数据复制.

ZooKeeper Service
zkservice.jpg-84.8kB

组建成Zookeeper服务的服务器必须能够知道彼此的存在. 它们维护着一份内存状态图, 以及事务日志和持久化存储的快照. 只要大部分的服务器是可用的, 那么Zookeeper就仍然可用.
客户端连接单个Zookeeper服务器. 这个客户端会通过发送请求, 接收响应,获取监控事件和发送心跳包去维护一个TCP连接. 如果这个TCP连接中断了, 那么客户端就会连接其他的服务器.

Zookeeper是有顺序的

Zookeeper会用一个反映事务顺序的数字去标记每一个更新. 以后的操作就可以用这些顺序去实现一个更高等级的抽象, 比如同步原语.

Zookeeper是快速的

Zookeeper在读主导的系统中会非常快. 在上千个机器的Zookeeper应用中, 读操作和写操作的比例大概在10:1的时候, 它的操作性能能够达到最好.

数据模型和分级命名空间

Zookeeper提供的命名空间很像标准的文件系统. 一个命名就是 / 分隔的路径元素. 在Zookeeper的命名空间, 每个节点就是被定义为一个路径.

ZooKeeper’s Hierarchical Namespace
zknamespace.jpg-34.6kB

节点和短暂节点

不像标准的文件系统, Zookeeper命名空间的每个节点都有一个相关联的数据. Zookeeper被设计来存储协调数据: 状态信息, 配置, 本地信息等等, 所以存储在每个节点的数据通常是很小的, 在字节到千字节的范围之内.
Zookeeper节点维护了一个状态数据结构, 其中包含了数据变化的版本号, ACL变化和时间戳. 这个状态数据可以用来缓存检验和协调更新. 每次Zookeeper节点变化, 版本号就会叠加. 无论何时客户端获取数据, 它也会接收到数据的版本.
在命名空间中数据的读写都是原子的. 读操作会获取所有与节点相关的数据, 而写操作也是全量替换更新的. 每个节点都有一个访问控制列表(ACL), 用来限制谁能够做什么.
Zookeeper也有一个短暂节点的概念. 只要创建节点的会话(session)是活的, 那么这个节点就会存在. 但是当会话结束了, 那么这个节点也会被自动删除.

条件更新和监控

Zookeeper支持监控的概念. 客户端可以在节点中设置一个监控. 当节点发生变化时, 监控就会触发. 以及如果客户端和服务器的连接中断了, 那么客户端将会接收到一个本地的通知.

保障

Zookeeper非常快速和非常简单. 因为它的目标是作为一个复杂系统服务的基础结构, 例如同步. 它提供了一系列的保障.

  • 顺序一致性: 来自客户端的更新会以它们发送的顺序来执行.
  • 原子性: 不管更新要么成功要么失败, 不会出现局部的结果.
  • 单一的系统映像: 一个客户端将看到相同的服务视图, 而不管它连接到哪个服务器.
  • 可靠性: 一旦更新被应用, 它将会从那个时候持久化直到客户端重写更新.
  • 及时性: 系统能够确保客户端看到最新的数据, 在一定的时间内.

简单的API

  • create: 在本地树上创建一个节点
  • delete: 删除一个节点
  • exists: 检测是否在本地树上存在这个节点
  • get data: 读取这个节点的数据
  • set data: 写入这个节点的数据
  • get children: 获取这个节点的子节点列表
  • sync: 等待数据传播到其他服务器

实现

Zookeeper组件(下图)展示了Zookeeper服务的高水平的组件. 除了Request Processor, 每一个Zookeeper服务器都会保存每个组件自身备份的副本.

ZooKeeper Components
zkcomponents.jpg-30.1kB

副本数据库是一个包含了整个数据树的内存数据库. 所有更新操作会记录到到磁盘日志中, 用于异常情况的恢复. 写操作也会在应用到内存数据库之前序列化到硬盘中.
每个Zookeeper服务器节点服务若干个客户端. 客户端连接到某一个指定的服务器节点(通过某种算法)和Zookeeper进行交互. 读请求由每个服务器的副本数据库来处理. 修改Zookeeper服务状态和写数据的请求需要通过一致性协议进行处理.
作为一致性协议的一部分, 所有写请求都会转发到一个称为 leader 的服务器中. 而剩余的服务器被称为 followers, 用于接收从leader 服务器发来的消息建议并同意进行传输消息. 消息层负责替换挂掉的 leader服务器, 以及同步leader服务器和followers服务器之间的数据.
Zookeeper使用了一个自定义的原子消息协议. 因为消息层是原子的, 所以Zookeeper可以保证本地副本不会出现分歧. 当leader服务器接收到一个写请求, 它会计算系统的状态在写操作被应用和转换到一个事务的时候, 并记录下新的状态.

使用情况

zookeeper的编程接口设计的非常简单, 用这些能实现一些其他更高级别的操作,比如同步原语,对成员进行分组和选举等等.

性能

Zookeeper被设计成高性能的协调框架, 下图是吞吐量随着读写比例变化的图表. Zookeeper 吞吐量和读写比例的变化关系用的是zookeeper3.2版本,运行在 双核 2Ghz 及SATA 15k RPM 处理器配置的服务器中. 写入请求是1Kb写入, 读请求也是1kb的读.

ZooKeeper Throughput as the Read-Write Ratio Varies
zkperfRW-3.2.jpg-41kB

在版本3.2中, 读写性能比起版本3.1提高了2倍

可靠性

为了展示系统随着时间而出现的错误行为, 我们用7个机器搭建了一个Zookeeper服务. 我们使用和此前一样饱和度的基准测试, 但是这次我们把写百分比保持在30%, 这个比例是对我们预期的负载的保守估计值.

Reliability in the Presence of Errors
zkperfreliability.jpg-68.2kB

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值