`
sharp-fcc
  • 浏览: 110836 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

zookeeper 入门 (来自官方文档)

阅读更多

来源于:

http://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#ch_guideToZkOperations

讲对于 zookeeper 编程的简介:

 

简介:

本文讲了如何应用zk的优势创建分布式应用,包含了如下几个部分.

 

首先4个章节从一个比较抽象的层面讲了zookeeper的概念, 这使读者能够理解zk怎么工作和这样使用zk工作. 他不包括源代码,假像读者熟悉分布式计算的问题. 以下是四个部分:

 

 

 

后面的四个部分提供了具体的编程信息:

 

如果读者是第一次使用zk, 你应该读 Zookeeper Data Model 和 ZooKeeper Basic Operations.还有 Simple Programming Example 会帮助你理解 zk 客户端编程的基本知识.

The ZooKeeper Data Model

zk有一个像目录结构一样的分布式文件结构.不一样的是在一个命名空间的每一个节点可以有子节点.这就像在一个文件系统中,他允许一个文件可以是目录. 节点的路径一定要规范,绝对的,用斜杠分割的,没有相对路径. 任何unicode 字符可以用做一条路径除了以下限制:

\u0000(null) 不能做一个路径.

以下编码不能作为path 因为 表现不好: \u0001 - \u0019  \u007F - \u009F  

以下编码不允许: \ud800 -uF8FFF, \uFFF0-uFFFF, \uXFFFE - \uXFFFF (where X is a digit 1 - E), \uF0000 - \uFFFFF

"." ".."只能作为名字的一部分
"zookeeper" 为系统保留

ZNodes

每一个节点在 zk中被称为 znode. Znodes 维护一个结构包括数据变化的版本号, acl变化.这种结构有个时间戳, 用这个时间戳去验证 cache和同步.每次数据变化, 数据的版本号增加.事实上, 当一个客户端检索数据的时候, 同时会收到数据的版本号. 当客户端更新或者删除数据的时候,也必须指明znode数据的版本,如果提供的版本号跟真实数据的版本号不一样, 更新失败.

Znodes 是一个程序员主要接触的.有几个特征值得关注.

 

Watches

客户端可以watch Znodes. 任何变化讲出发这个 watch.当一个watch触发了, zk会给客户端一个通知. 

 

Data Access

存在znode中的数据自动读写. 读的话是从一个znode中读出左右的数据流,而写的话会覆盖所有的数据.没一个node有一个权限控制列表(ACL) 限制谁可以做这个.

zk的设计初衷不是为了作为一个db或者大对象存储. 而是管理需要协作的数据.这种数据的形式可以是配置文件,状态信息,集结信息等等.  需要协作的数据的一个公共的特点是: 他们都很小,以kb 来衡量.zk客户端和服务端都会检测保证znodes是一个小于1M的数据,真实情况是 应该比1M小很多.操作大数据将导致一些操作话很多时间,有可能将一些操作延时, 需要将数据从网络上从一个地方移动到另外一个地方.如果存储打数据是必须的, 可以考虑大数据存储系统. 比如NFS或者 HDFS, 然后在zk上存储数据的指向.

 

 

 

Ephemeral Nodes

zk有个 临时节点的概念, 当且仅当连在这个znode的 session 存在的时候, 临时节点存在.当这个session消失,znode删除.由于这种行为, 临时节点不允许有字节点.

 

 

 

Sequence Nodes -- Unique Naming

当创建znode的时候, zk同时分配一个递增的计数器指向地址的最后. 这个计数器跟父节点的不一样.这个计数器用来帮助父节点存储存储队列中的下一个数字.当到2147483647 的时候,会从头开始.

 

Time in ZooKeeper

Zxid

对于zk状态的改变用一个叫做 zxid(ZooKeeper Transaction Id)的形式存储. 用来对zk的改变做一个顺序的记录.每一个改变用一个不一样的zxid.如果 zxid1 比 zxid2 小,那zxid1 在zxid2 之前发生.

Version numbers

znode的每一次变化将会导致 znode的版本号增加.一个znode有如下三种版本号. version:znode 数据变化的次数,cversion: znode子节点变化的次数.aversion: ACL变化次数

Ticks

当我们在多台server上搭建 zk的时候, server用 ticks 来定义像 状态上传, session 超时, 在peers中连接超时等的时间.tick time 只是不直接显示了最小session 超时时间(tick time的两倍).

Real time

zk不用真实的时间,而把时间戳放到znode的 状态结构中,当这个znode创建或者修改的时候.

 

 

 

ZooKeeper Stat Structure

zk中每一个znode的状态结构由以下域组成:

czxid:

创建这个znode的 zxid.

mzxid:

最后一次修改这个znode的zxid.

ctime:

以毫秒为单位,这个znode创建的时间.

mtime:

以毫秒为单位, 最后一次修改这个znode的时间.

version:

这个znode被修改的次数.

cversion:

这个znode子节点被修改的次数.

aversion:

这个znode ACL被修改的次数.

ephemeralOwner:

如果这是一个临时节点, 存储的是session的id.如果不是临时的, 是0.

dataLength:

这个znode的数据长度.

numChildren:

这个znode的子节点的数量.

 

ZooKeeper Sessions

zk客户端通过一个叫做通道(handle)的东东来跟服务端创建一个session.一旦建立起连接,这个handle从CONNECTION 状态开始. 客户端尝试连上一个服务端的server,然后把状态改为 CONNECTED.一般情况下,handle只会有这两种状态.如果一个不可避免的错误发生,比如session超时, 验证失败,应用关闭handle, 这个handle将是CLOSED状态.

下图展示了可能的状态转换:

 

 

 

 

 

 

 

创建一个连接, 应用层必须提供的一个可以连接的以逗号分割的主机列表,zk server的地址:(e.g. "127.0.0.1:4545" or "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"). 客户端将随机选择一个server 尝试连接. 如果连接失败,客户端将重新从list中自动选择下一个server,自动连接建立.

 

Added in 3.2.0:一个可选的"chroot"后缀可以加载一个连接请求后面.用起来像是这样: "127.0.0.1:4545/app/a" or "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a" 当一个客户端在 /app/a  是所有者.那请求的路径可以是相对路径,比如 getting "/foo/bar" 将导致一下命令被执行"/app/a/foo/bar".这种特性适用于多租户的环境下,每个租户用 zk的一部分.而编码的时候可以重用一部分代码.

 

当一个客户端得到 zk service 的handle的时候, zk创建一个 zk session, 表现为一个64 bit的数字,  分配给这个客户端.如果这个客户端连上不同的server, 他会把这个 session的id 作为握手协议的参数传过去, 作为一个安全措施, 这个server会创建这个session的 密码, 所以所有的server都可以验证.这个密码在创建的时候随着 id 一起传给客户端.客户端在重新建立这个session的时候把这个session和密码一起传给新的server.

 

当一个客户端如果被zk 集群划分(比如按照ip 做hash) , 客户端会到list中寻找特定的server 在session创建的时候.最终, 在客户端,服务端在重新建立连接后, session会过度到 "connected"状态(在 session 超时时间内)或者到"expired"状态(在 session 超时时间外). zk并不鼓励在断掉连接的时候创建一个新的对象.(new  ZooKeeper.class or zookeeper handle). zk 客户端库中会处理重连. 仅当 你被通知 session 超时的时候再去创建新的session.

 

session超时被zk集群自己管理,而不是客户端.当session 建立的时候会提供一个"timeout"的属性.这个属性用在集群中决定什么时候客户端的session 超时.超时发生在集群在特定的时间内没有收到客户端的回应.在session 超时的时候,集群会删除这个session创建的所有的临时节点, 通知所有连着的客户端这个变化. 从这个意义上来讲, 超时的这个session 将不会收到session超时的通知,直到TCP 连接被再次建立.

 

以下是session超时时候的状态转换,被 watcher 看到的:

1. 'connected' session被创立,客户端 ,服务端无障碍交流.

2. ... 客户端被划分,重新选择服务器.

3. 'disconnected' : 客户端跟服务端失去连接.

4. ... 时间流逝,在'timeout'之后 集群将session 超时, 什么都不会被客户端看到.

5. ... 时间流失, 客户端恢复网络,跟集群建立连接.

6. 'expired': 最终客户端重连上 集群,被通知超时.

 

另外session的一个参数是 默认 watcher. 客户端watcher 在状态改变的时候被通知.比如说, 客户端跟集群失去连接会接到通知.在新连接这种情况下, 第一个给watcher的事件往往是 session 连接的时间.

 

这个session 会持续保持活跃. 如果一个session 在一段时间内是闲置的,将会导致这个session 超时,这个时候,客户端就会发送PING 来保持这个连接活跃.这个PING 不光是让服务端知道客户端是活着的, 也让客户端保证服务端的连接是好使的.PING的时间足够让各方来识别这条连接.

 

一旦这条连接建立起来,有两个原因让客户端代码抛出 connectionloss的异常.

1. 客户端想对已经无效的连接做操作.

2. 如果一些异步调用当连接已经断掉的时候.

 

Added in 3.2.0 -- SessionMovedException.   

这是一种不被客户端发现的内部错误.这种异常在收到在不同server 已经建立连接的情况. 详细点说这种情况, 客户端发送一个请求给一个server , 由于网络堵了, 客户端超时, 连接一个新的server.网络又通了, 请求发送到老的server上,老的server发现session已经转移,关掉这个连接.客户端不会收到这种异常,因为他根本不会从老的连接读东西.一种情况会在客户端出现这种异常,就是两个客户端尝试用重新连接,用这个 session的id, 和 密码.一个将正确的建立连接.另外一个会超时.

 

ZooKeeper Watches

所有从zk读的操作 getData()getChildren(), and exists() 都有一个选项,设置一个watch 进去处理副作用.这里是zk定义的watch的定义: 一个监听的 watch是一个一次性的触发器,当客户端设置的数据变化的时候触发.以下三个关键点帮助理解watch:

One-time trigger

一个watch的时间在数据发生变化的时候发送到客户端.举个例子, 如果一个客户端执行 getData("/znode",true)的操作,然后/znode 变化或者被删除的时候,客户端会收到一个事件.如果/znode再次变化, 将不再有事件发送到客户端.除非客户端get了其他数据.

Sent to the client

假设一个事件在到客户端的路上,但是有可能没有达到客户端,在发起改变的客户端收到正确的返回码之前.到watchers 的都是异步的操作. zk保证了顺序: 一个客户端将永远不会在收到watch 事件之前看到变化.网络延迟或者i其他因素可能导致不同的客户端看到返回值和 watch 不一样.关键是被不同客户端看到的将有一致性的顺序.

The data for which the watch was set

一个节点有好几种改变的方式. zk维护两种watch: 数据 watch 和字节点watch. getData 和 exists  设置数据 watch.getChildren设置 自己点 watch.   getData 和 exists返回节点的数据,  getchildren 返回字节点的一个list.因此, setData将触发数据watch.成功的 create 将出发 数据 watch 和 字节点watch. 同理是delete操作.

 

watches 在zk server的本地进行管理.这样方便轻量级的set,维护和分发. 放一个客户端连到一个新的 server,这个watch将包括所有的session 事件.在连接断掉之后就收不到watch了.当一个客户端重连,所有之前注册的 watch将被重新注册和触发.一般来说,这对上层是透明的.

 

 

What ZooKeeper Guarantees about Watches

关于watches. zk做了如下保证:

watches的东西在其他事件,其他watches 或者异步的回复是有序的.zk 客户端库可以保证这一点.

在看到数据更新之后的新数据之前客户端可以收到watch事件.

客户端看到的 watch 事件的顺序 跟时间服务端改动的顺序是一样的.

 

Things to Remember about Watches

watches是一次性的.如果想看到数据未来的变化,设置另外一个watcher.

 因为watch是一次性的,在得到事件和发送新的请求得到一个watch, 有可能看不到每一次的变化.准备好处理一种情况:znode改变了很多次,在得到事件和设置新的watch之间.

一个watch对象,只会被通知一次.比如说,一样的watch对象注册同一个exist事件.对于同一个文件.这个文件被删除,这个对象只会被调用一次.

当你从server失去连接.不会收到任何事件直到重连.可以使用 session 事件保证程序的严谨性.

 

ZooKeeper access control using ACLs

zk用ACL做权限控制。ACL跟unix很像,每一个节点都有标识位。跟unix不一样的是,一个znode不仅仅局限于三种权限控制,owner,group,and other。zk没有owner的概念,取而代之的是有个id的set的集合, 权限跟这些id息息相关。

这些ACL的权限控制只针对一个znode,不包含子节点们,对于子节点不起作用。举个例子, /app 对于 10.3.24.13可读,而 /app/status 对于所有可读。也就是说ACL不具有递归性。

zk支持那种可插入的身份验证。id可以作为身份验证的一种方案,举个例子: ip:172.16.16.1  就是172.16.16.1 的id。

当客户端连接zk ,验证自己的时候,zk从id列表中查找这个客户端,同时检测这些znode的 ACL权限,比如说, (ip:19.22.0.0/16, READ)  给了任何 ip是 19.22 开头的机器读的权限。

ACL Permissions

zk支持如下几种权限:

CREATE: 创建子节点

READ:读取节点和子节点

WRITE:往节点写数据

DELETE:删除子节点

ADMIN:管理权限

对于CREATE 和 DELETE的权限需要更加细粒度的控制,这种情况如下:

如果一个客户端在一个znode中添加了一个节点,他想让所有的客户端都有加节点的权限,但是只有他自己有删除的权限。

。。。 翻译不下去了,此处省略几十行

 

Consistency Guarantees

 zk是一个高性能, 高伸缩的服务。读写的新能都十分优越,尽管读比写更加高效。原因是在读的情况下,zk能够提供老数据,这主要归功于zk一致性的保证。

Sequential Consistency

客户端的更新能够严格按照他发出去的请求顺序。

Atomicity

更新要么成功要么失败,不会出现部分成功,部分失败的情况。

Single System Image

一个客户端只会看到一种情况不管他连接的是哪台server。

Reliability

当一个更新被执行的时候,效果会永久存在直到客户端覆盖这个更新。这个保证有两个推论:

1.  如果一个客户端得到更新成功的返回值,这个操作肯定被执行了。

2.  更新的变化,读或者一次成功的更新,将永远不可能回滚。

Timeliness

在一段时间内,客户端获取的东西总是实时的。

用这些一致性的保证,可以实现更加高级的功能。比如说leader选举,队列,可撤销的读写操作,更多用法请见:Recipes and Solutions

Bindings

Java Binding

 有两个包组成了java binding:org.apache.zookeeper and org.apache.zookeeper.data.

其他的包组成了server端实现的data包里是一些生成的class 作为容器使用的。

java中main class 是zookeeper ,他的两个不同的构造函数只是 session id 和password的区别,他支持session恢复通过一个process的实例,一个java程序能够吧session id 和 password存储起来,重启之后能用到早期程序中的 session id 和password。

zookeeper 实例被创建之后,两个线程起来:一个IO线程,一个处理事件线程,所有IO操作都通过IO线程实现(用java nio),所有事件的回调都通过那个事件线程处理。session的维持,包括zk的重连和维持心跳,都通过IO线程完成,所有事件的监听都通过事件线程。这种设计有几个注意点:

所有完整的异步调用和watcher的回调都按照顺序进行,一次一个,但是当线程处理的时候是不会有任何反馈的。

回调不会阻塞IO线程或者其他的同步调用。

同步调用可能不会按照顺序返回。举个例子:如果一个客户端做了如下操作:假设一个异步调用读取 /a 节点,同时设置watch 为true,然后同步去读 /a 的内容。

如果这个时候 改变a的值,在异步调用和同步调用之间,客户端库会收到事件说 /a 已经被改变,时间实在同步调用之前,整个回调在阻塞event queue,这个同步的读将会先返回 a的最新的值。

 

 

 

分享到:
评论

相关推荐

    zookeeper 入门到精通

    ### Zookeeper 入门到精通 #### 一、Zookeeper 概述 ##### 1.1 什么是 Zookeeper? Zookeeper 是一个分布式的协调服务框架,最初由雅虎实验室开发,后来成为 Apache 的顶级项目。它是 Google Chubby 的一种开源...

    Zookeeper入门到精通 教学视频及文档

    《Zookeeper入门到精通》教学视频及文档涵盖了分布式协调服务Zookeeper的核心概念、安装配置、基本操作以及在实际应用中的高级技巧。Zookeeper是Apache Hadoop项目的一个子项目,它为分布式应用程序提供高效且可靠的...

    zookeeper系列1:入门

    对于想要深入了解Zookeeper的读者,可以通过阅读官方文档、在线博客(如给出的博客链接:[iteye博客](https://425826501.iteye.com/blog/2424450))和开源社区的讨论来扩展知识。同时,深入研究源码有助于理解其内部...

    zookeeper入门练习demo

    **Zookeeper入门练习Demo** Zookeeper是一个分布式协调服务,由Apache Hadoop项目开发,广泛应用于分布式计算、配置管理、命名服务、分布式锁等场景。这个"Zookeeper入门练习Demo"旨在帮助初学者快速掌握Zookeeper...

    zookeeper3.4.6 pdf文档

    《Zookeeper 3.4.6 PDF 文档》是一份详尽介绍 Zookeeper 的资源集合,其中包含了多个方面的内容,包括 Zookeeper 的基础概念、编程指南、管理员手册以及实际应用案例。Zookeeper 是一个分布式协调服务,常用于管理...

    zookeeper入门文档

    Zookeeper 是一个分布式服务框架,由 Apache Hadoop 项目衍生而来,主要解决的是分布式环境中的数据一致性问题。它提供了一个类似文件系统的目录节点树结构,用于数据存储,并且支持多种重要的服务,例如统一命名...

    Zookeeper从入门到精通课程资源(未加密)

    通过学习《Zookeeper从入门到精通课程资源》,你可以深入了解Zookeeper的工作原理,掌握其核心功能,以及如何在分布式系统中有效利用Zookeeper解决实际问题。配合提供的"zookeeper视频汇总.txt",系统学习将更加高效...

    ZooKeeper入门简介及配置使用PDF

    在“ZooKeeper入门简介及配置使用”文档中,你将学习到以下关键知识点: 1. **ZooKeeper的基本概念**:了解ZooKeeper的核心组件,包括服务器节点、客户端、会话、Watcher、ZNode(ZooKeeper的数据节点)等。理解...

    ZooKeeper入门培训

    在公司内部做培训时自己整理的zookeeper入门文档,分享给大家。 主要章节有: 1、基本概念 2、安装配置 3、简单操作 4、Zookeeper的api使用 5、Zookeeper的典型应用场景 【注意】仅供个人学习使用,非本人同意,请勿...

    大数据技术领域Hadoop组件ZooKeeper入门体验

    内容概要:本文档分为三个主要部分介绍了如何开始使用 ZooKeeper:第一部分是首次启动并体验ZooKeeper,涉及服务器的启动和基本的状态查询;第二部分则是关于ZooKeeper配置的基本理解和修改,特别是客户端的最大连接...

    DUBBO+Zookeeper小例子

    4. **Maven**:项目管理工具,用于管理Java项目的构建、报告和文档。在本例中,Maven用于依赖管理和构建过程,确保所有所需库正确地被引入并编译。 在实现"DUBBO+Zookeeper小例子"时,你需要遵循以下步骤: 1. **...

    Dubbo入门搭建zookeeper集群+服务端消费端demo

    1. `dubbo 入门及安装总结.docx`:这个文档可能包含了Dubbo的基本概念、安装步骤、配置详解以及常见问题解答,是你快速了解和上手Dubbo的重要参考资料。 2. `服务端和消费端demo.rar`:这是一个包含服务端和消费端...

    zookeeper-3.4.8.zip

    《Zookeeper 3.4.8 入门详解:打造分布式协调服务基石》 Apache ZooKeeper 是一个开源的分布式协调服务,它为分布式应用程序提供了一个简单一致的接口,用于管理命名空间、配置维护、分布式同步和组服务。在这个...

    dubbo + zookeeper+springmvc 入门级学习资料

    2. **搭建Zookeeper**:按照Zookeeper的官方文档配置并启动Zookeeper服务器,为Dubbo提供服务注册与发现的平台。 3. **创建服务提供者**:使用SpringMVC构建一个简单的Web应用,然后引入Dubbo的依赖,编写服务接口...

    分布式系统协调服务 ZooKeeper 的安装与使用入门

    内容概要:本文详细介绍了 Apache ZooKeeper 的基础知识、安装步骤以及基本操作。首先,从下载和解压安装包开始,然后...阅读建议:在学习过程中可以结合官方文档进行深入研究,并尝试在实际项目中应用所学的知识点。

    ZooKeeper分布式协调服务:从入门到实战详解

    内容概要:本文档详细介绍了ZooKeeper这一开源分布式协调服务的技术细节及其应用。首先,从基本概念、数据结构、集群架构等方面入手,帮助读者全面了解ZooKeeper的基础知识。接下来,深入探讨了ZooKeeper的安装配置...

    dubbo+zookeeper开发案例

    6. **学习资源**:为了更好地理解和实践这个案例,初学者可以查阅Dubbo、Zookeeper和Spring的官方文档,以及相关的技术博客和教程,如《Dubbo开发者指南》、《Zookeeper实战》等书籍,以加深对这些技术的理解。...

    flink入门文档.pdf

    Flink 入门文档 Flink 是一个大数据处理框架,具有批流一体、高容错、高吞吐、低延迟、大规模计算、多平台部署等核心特点。本文档将对 Flink 的核心概念、架构、API 层次进行详细介绍。 1. 核心概念 Flink 是一个...

    Kafka官方中文文档.pdf

    Apache Kafka是一个分布式流处理平台,它具备三个...综合来看,这份Kafka官方中文文档提供了一套全面的知识体系,详细介绍了Kafka的架构、使用、配置、操作和安全等各方面知识,是理解和掌握Kafka技术的重要参考文献。

    jstorm 阿里巴巴官方文档 pdf

    在《JStorm阿里巴巴官方文档》中,你还会看到许多示例代码,比如压缩包内的"storm-book-examples-ch02-getting_started-8e42636",这个文件很可能是第二章关于入门示例的代码。通过这些例子,你可以动手实践,加深对...

Global site tag (gtag.js) - Google Analytics