ZooKeeper编程向导——源自官方文档
ZooKeeper编程向导——源自官方文档
介绍(源自ZooKeeper官方文档) 学习HBase过程中,发现它与ZooKeeper的关系比较密切,于是专门学习了一下ZooKeeper,下面是ZooKeeper官方文档的半翻译版(我(magic-sulin)并非一字一句的照抄,而是写入了自己的理解)。此文档是为了向那些希望使用ZooKeeper协调优势自己分布式应用的人提供编程向导,它包含了理论和实战两部分!前四节将对ZooKeeper进行理论上比较深入的探讨,这对我们理解ZooKeeper的工作原理和怎么使用ZooKeeper非常重要。此四节不包含编程的源代码,但是它会通过讲解一些分布式计算相关的问题来让你对ZooKeeper加深了解:
ZooKeeper数据模型 ZooKeeper有一个属性的命名空间,它更像一个分布式文件系统。不同之处在于此命名空间中的每个节点可以访问它自身的数据和子节点的数据。节点的路径总是以斜杠分开这样的形式(/node/childNode)表示。ZooKeeper的路径可以以任何的Unicode字符组成,除了下列这些情况:
ZNode ZooKeeper路径中的每个节点都叫做一个ZNode。Znode持有一个状态数据结构,此结构中包含数据更新的版本号、访问权限(ACL)更新的版本号、时间戳。这些版本号和时间戳使ZooKeeper可以验证缓存有效性和协调更新。每当ZNode中的数据更新时,版本号都会递增。例如,当客户端获取数据时,它(客户端)也会接收到此数据对应的版本号。当此客户端下次执行更新(或删除)数据操作时,它必须向ZNode提供这些数据的版本号(是客户端当前持有的版本号)。如果此版本号与ZNode本身的版本号不一致,即其他客户端已经更新了此数据,那么此更新就会执行失败。 提示:在分布式应用工程中,节点可以是一个正常的主机、一个服务器、一个集群、一个客户端程序等等。在ZooKeeper文档中,ZNode表示这些数据节点在ZooKeeper服务器中的引用。quorum peers表示ZooKeeper集群中的服务器。客户端表示任何使用ZooKeeper服务的主机或进程。 ZNode是我们编程访问的主题,上面的提示非常值得引起你的注意! Watches 数据访问:命名空间中存储在每个ZNode中数据的读写操作都是原子性的,读操作会获取与此ZNode相关联的所有数据字节,写操作会替换所有数据。每个节点都会有一个权限限制列表(ACL),此列表会约束哪些客户端有权对此ZNode做哪些数据操作。ZooKeeper并没有被设计为常规的数据库或者大数据存储。相反的是,它用来管理调度数据,比如分布式应用中的配置文件信息、状态信息、汇集位置等等。这些数据的共同特性就是它们都是很小的数据,通常以KB为大小单位。ZooKeeper的服务器和客户端都被设计为严格检查并限制每个ZNode的数据大小至多1M,当时常规使用中应该远小于此值。关系型大数据的操作会导致一些其他操作耗费更多的时间,并且因为大数据的网络传输和写入存数介质速度过慢也会导致其他操作的延迟。如果你需要存储大数据库,通常的做法是将这些大数据存储在NFS或HDFS中,然后将这些大数据的存储位置指针存储在ZooKeeper的ZNode中。 瞬时ZNode:ZooKeeper中也有瞬时ZNode的概念,这些ZNode仅存在于创建此ZNode的会话的有效期内。当此会话结束后此ZNode也会被删除,由于瞬时ZNode的特性,它不能有子节点。 顺序节点 -- 唯一命名:当创建一个ZNode时候,你也可以请求ZooKeeper将一个单调递增计数器添加在路径之后。此计数器对于父节点是唯一的。------??? ZooKeeper中的时间 ZooKeeper可以以不同的方式跟踪时间:
ZooKeeper的状态结构 ZooKeeper中每个ZNode的状态数据结构都是由下列字段组成
ZooKeeper会话(Sessions) ZooKeeper客户端可以通过创建一个ZooKeeper的句柄,从而与ZooKeeper服务建立一个会话(session)。会话创建之后,句柄的初始状态为CONNECTING状态,此时客户端句柄会尝试与ZooKeeper服务器建立连接,此服务器会指明此句柄将状态设置为CONNECTED。在常规操作中只会有这两种状态,如果有任何不可恢复的错误发生,比如会话失效、权限验证失败、应用强制关闭句柄等等,此句柄状态会转变为CLOSED状态。下图展现了客户端句柄可能出现的状态转换:
3.2版本新添加:一个可选后缀“chroot”也可以添加在连接字符串末尾,那么在所有与此根路径相关的路径解释时都会执行此指令(与unix的chmod指令相似)。例如若连接字符串为“127.0.0.1:3000,127.0.0.1:3002/app/a”,那么客户端会将根目录建立在/app/a路径中。所有路径的根目录都会被重定向到此目录。如/foo/bar路径的读写操作都会被重定向到/app/a/foo/bar路径(从服务器端看是这样的)。这项新添加的功能在多应用公用ZooKeeper时非常有用,此功能使每个应用都能更简便的处理路径指定,就好像每个应用都在使用“/”路径一样。 当客户端从ZooKeeper服务获取到一个句柄,那么ZooKeeper服务会创建一个ZooKeeper会话,此会话以64bit的数字表示。之后ZooKeeper服务将此会话分配给客户端。如果客户端下次连接到其他的ZooKeeper服务器,那么客户端会将先前获取到的会话ID作为连接握手的一部分发送。出于安全考虑,ZooKeeper服务器会为每个会话ID创建一个所有ZooKeeper服务器都可以检验的密码,此密码会在客户端建立会话时随着会话ID一同发送给客户端。那么客户端会在下次与新的ZooKeeper服务器建立会话时将此密码与会话ID一同发送。 客户端创建ZooKeeper会话时会发送一个会话超时时间毫秒值参数,客户端发送一个请求的超时时间,服务器会响应一个它可以给客户端的超时时间。当前的实现要求此值最小必须为心跳时间(心跳时间在服务器配置文件中指定)的二倍,最大不得超过为心跳时间的二十倍。ZooKeeper客户端API允许协商超时时间。 当客户端会话与ZK服务断开连接之后,客户端会搜索创建此会话的服务器列表。若最终此会话与至少一个ZK服务器重新建立连接,那么此会话会被重新转换为CONNECTED状态;若在超时时间之内不能重新建立连接则此会话会被转换为expired状态。我们不建议你为断开连接的会话重新建立新的会话,因为ZK客户端库会自动为你的会话重新建立连接。特别是我们已经启发式的将ZK客户端库建立为处理类似于"羊群效应"这种情况,你最好只在收到会话失效通知的情况下才重新建立会话。 会话失效是由ZK服务器管理的而不是客户端,当客户端创建一个会话时,它会按上文描述的那样提供一个会话超时时间,ZK服务器会根据此值决定当前会话是否超时。若在超时时间之内ZK服务器没有收到客户端的消息(除了心跳),则ZK服务器会判定此会话超时无效。在会话无效之后,ZK服务器会删除所有此会话创建的瞬时节点并且立即通知其他每个监视这些节点且未断开连接的客户端(他们监视的瞬时节点已不存在了)。此时这个失效会话与ZK集群仍然处于断开连接状态,此会话客户端不会收到上述通知除非此客户端又重新建立了到ZK集群的连接。此客户端会一直处于未连接状态直到与ZK集群的TCP连接重新被建立,此时这个失效会话的监视者将会收到一个会话失效("session expired")通知。 下述为一个超时会话在它的监视者眼中的状态转换实例:
ZK会话建立的另一个参数叫做默认监视者。在客户端有任何状态改变发生时监视者(在ZK服务器端)都会得到通知,例如,如果客户端与ZK服务器实现联系则客户端(?)会得到通知,或者如果客户端会话失效也会得到通知等等。监视者将客户端的初始状态当做未连接状态(disconnected:在任何状态改变事件被客户端库发送至监视者之前)。在新连接建立时,发送至监视者的第一个事件通常都是会话连接建立事件。
3.2版本新添加 -- SessionMovedException:有一个客户端不可见的内部异常叫做SessionMovedException,此异常会在ZK服务器收到了一个指定会话的连接请求,但此会话已经在其他服务器上重新建立了连接时发生。此异常发生通常是因为一个客户端向一个ZK服务器发送一个请求,但是网络包延迟导致客户端超时而与一个新的服务器建立连接。之后当这个延迟了的网络包最终慢吞吞到达最初的ZK服务器时,ZK服务器检测到此会话已经被移动到另外一个ZK服务器上面并且关闭连接。客户端通常不会发现此异常因为他们不会从旧的连接中读取数据(这些旧连接通常都是已关闭的)。此异常出现的一种情况是当两个客户端都尝试使用同一个会话ID和密码与ZK服务器建立相同的连接。这两个客户端中的一个会成功建立连接而另外一个则会被断开连接。 ZooKeeper监视(Watches) ZooKeeper中的所有读操作(getDate(), getChildren(), exists())都有一个设置监视者的选项。ZooKeeper中监视者的定义为:一个监视事件是一次性的触发器,此触发器会在监视数据发生改变时被触发并发送给设置此监视器的客户端。以下为一个监视器定义的三个关键点:
监视器被客户端所连接的ZK服务器所持有,这允许监视器可以被轻松的设置、维持和发送。当此客户端连接到一个新的ZK服务器,监视器会被以任何会话事件激活(?)。当客户端与ZK服务器断开连接则它不会再收到任何监视事件。当客户端重新建立连接,先前注册的监视器都会被重新注册并且根据需要被激活。通常这一系列操作都是透明进行的,有一种情况下,监视器也许会出现失误:监视的节点在先前客户端断开连接期间已经被创建和删除。 ZooKeeper对监视器的保证 对于监视器,ZooKeeper有以下保证:
ZK监视器中应该记住的事:
ZooKeeper使用ACL进行权限控制 ZK使用ACL来控制指定ZNode的访问,ACL的实现与Unix文件访问许可非常相似:它用许可bit位来表示一个ZNode上各种操作的允许或不允许。与标准Unix许可不同的是,一个ZK节点的访问权限并不为特定的三种用户(拥有者、用户组、全局)范围限制。ZK并没有一个节点拥有者的概念,ZK通过指定ID和这些ID相关联的许可来进行权限限制。要注意的是一个ACL只与指定的ZNode有关,尤其注意的是,这个ACL并不作用于子节点,如果/app仅对于ip:172.0.0.1可读但是/app/status却可以对所有IP都可见。因为ACL并不会覆盖子节点的ACL。 ACL权限 ZooKeeper支持下列权限:
CREATE和DELETE权限已经从WRITE中提取出来了,这样做是为了更加细微的权限控制。CREATE和DELETE分割出来的原因是:你想让一个客户端只能修改一个ZNode中的数据但是不能创建或删除子节点。ADMIN权限的存在是因为ZK没有ZNode拥有者这个概念,因此ADMIN权限可以扮演拥有者这个角色。ZK不支持LOOKUP权限,ZK内在的设定所有用户都有LOOKUP权限,这允许你可以查看ZNode的状态,但是你只能看这么多。(问题是,如果你想要在一个并不存在的ZNode上调用zoo_exists(),那么并没有权限列表进行判断是否有权限,因此ZK才内含所有人都有LOOKUP权限)。 ACL的固定模式 ZooKeeper有下列的固定模式
确保全局一致性 ZooKeeper是一个高性能的、可伸缩的服务。读写操作都被设计为尽可能快的。尽管读操作通常都比写操作要快很多,读写同样快的原因是对于读操作而言,ZK会返回更旧的数据,反过来而言,这正是由于ZooKeeper的一致性保证。
使用这些一致性保证,我们能很容易的在客户端构建更高层次的功能,比如领袖选举、队列、可回滚读写锁等等。 Java Binding(还有C呢,我不用它) ZK客户端库中有两个包组成了ZK binding功能:org.apache.zookeeper和org.apache.zookeeper.data。其余的包是被其内部使用的或者仅仅是服务器实现的一部分,开发者不必了解。org.apache.zookeeper.data包由一些被简单的用作容器的普通类组成。
最后,ZK客户端的关闭过程也很简单:当ZooKeeper对象被主动关闭或者收到一个致命的事件(SESSION_EXPIRED和AUTO_FAILED),ZooKeeper对象就会变为无效状态。关闭时,两个线程都会被关闭并且之后任何在此ZooKeeper之上的操作都是未知结果的,这种操作应该被避免。 异常处理:ZK操作时有可能会出现异常KeeperException,如果在此异常上调用code()方法会获取到特定的错误码。你可以查看API文档查看具体的异常详情和不同错误码代表什么意思。 |
ZooKeeper编程向导——源自官方文档相关推荐
- spark之4:基础指南(源自官方文档)
spark之4:基础指南(源自官方文档) @(SPARK)[spark, 大数据] spark之4基础指南源自官方文档 一简介 二接入Spark 三初始化Spark 一使用Shell 四弹性分布式数据 ...
- 提高编程水平的一段必经之路,研读官方文档
刚才看了 论坛里 jinxfei 的十年总结(14):从CS转向BS, 说实话,大部分内容我没有太仔细的看,不过如下的一段引起了我的注意: 真正让我心里有底的,还是在看了官方文档之后:http://s ...
- dubbo官方文档_狂神说SpringBoot17:Dubbo和Zookeeper集成
狂神说SpringBoot系列连载课程,通俗易懂,基于SpringBoot2.2.5版本,欢迎各位狂粉转发关注学习.未经作者授权,禁止转载 分布式理论 什么是分布式系统? 在<分布式系统原理与范 ...
- clickhouse官方文档_clickhouse分析:zookeeper减压概述
点击上方蓝字关注我们 " 使用复制表之后,随着数据量的增加,zookeeper是瓶颈?这个问题估计任何一个对ch关注的人都会看到,当然解决这个问题是需要花费较大精力的.本次我主要想分享ch官 ...
- ZooKeeper官方文档学习笔记03-程序员指南03
我的每一篇这种正经文章,都是我努力克制玩心的成果,我可太难了,和自己做斗争. ZooKeeper官方文档学习笔记04-程序员指南03 绑定 Java绑定 客户端配置参数 C绑定 陷阱: 常见问题及故障 ...
- ZooKeeper官方文档学习笔记01-zookeeper概述
纠结了很久,我决定用官方文档学习 ZooKeeper概述 学习文档 学习计划 ZooKeeper:分布式应用程序的分布式协调服务 设计目标 数据模型和分层名称空间 节点和短命节点 有条件的更新和监视 ...
- CUDA10.0官方文档的翻译与学习之编程接口
目录 背景 用nvcc编译 编译工作流 二进制适配性 ptx适配性 应用适配性 C/C++适配性 64位适配性 cuda c运行时 初始化 设备内存 共享内存 页锁主机内存 可移植内存 写合并内存 映 ...
- mysql5.5配置向导官方文档【中文翻译版】
这是mysql的官方文档的翻译版本,浏览器翻译的,基本上能看懂.图片看着更加方便.就是看着发虚,可以直接点击图片看大图. MySQL5.5配置向导中文说明
- CDH6官方文档中文系列(2)----Cloudera安装指南(安装前)
Cloudera安装指南 最近在学习cdh6的官方文档,网上也比较难找到中文的文档. 其实官方英文文档的阅读难度其实并不是很高,所以在这里在学习官方文档的过程中,把它翻译成中文,在翻译的过程中加深学习 ...
最新文章
- 学习 jQuery UI
- docker 挂载主机目录访问报错Permission denied 解决办法
- Day 08 周六下午的活动
- SAS 对数据的拼接与串接
- phpstudy更改但是php版本没变
- 每日一博 - 常见的Spring事务失效事务不回滚案例集锦
- 接口结构_适用于Mac系统的API接口调试应用
- 第4章 Python 数字图像处理(DIP) - 频率域滤波2 - 复数、傅里叶级数、连续单变量函数的傅里叶变换、卷积
- Java讲课笔记16:内部类
- android 中如何监听耳机键消息
- Java之品优购课程讲义_day12(6)
- 【Gym - 101234G】Dreamoon and NightMarket 【子集中第K大元素】
- Androidd 高德地图功能系列开发(搜索模块)
- Java 使用记事本编写第一个java程序
- 计算机毕业设计ssm鹊巢大连分公司分销商管理系统51g9m系统+程序+源码+lw+远程部署
- IP-SAN存储技术
- 捣鼓PlantUML
- Python 100道基础入门练习题(附答案)【这期完结】
- 人工智能2021年10大应用
- 如何防御DDOS等流量攻击