Zookeeper Client简介

直接使用zk的api实现业务功能比较繁琐。因为要处理session loss,session expire等异常,在发生这些异常后进行重连。又因为ZK的watcher是一次性的,如果要基于wather实现发布/订阅模式,还要自己包装一下,将一次性订阅包装成持久订阅。另外如果要使用抽象级别更高的功能,比如分布式锁,leader选举等,还要自己额外做很多事情。这里介绍下ZK的两个第三方客户端包装小工具,可以分别解决上述小问题。

一、 zkClient
zkClient主要做了两件事情。一件是在session loss和session expire时自动创建新的ZooKeeper实例进行重连。另一件是将一次性watcher包装为持久watcher。后者的具体做法是简单的在watcher回调中,重新读取数据的同时再注册相同的watcher实例。

zkClient简单的使用样例如下:


上面是订阅children变化,下面是订阅数据变化


订阅连接状态的变化:


下面表格列出了写操作与ZK内部产生的事件的对应关系:

**event For "/path"** **event For "/path/child"**
**create("/path")** EventType.NodeCreated NA
**delete("/path")** EventType.NodeDeleted NA
**setData("/path")** EventType.NodeDataChanged NA
**create("/path/child")** EventType.NodeChildrenChanged EventType.NodeCreated
**delete("/path/child")** EventType.NodeChildrenChanged EventType.NodeDeleted
**setData("/path/child")** NA EventType.NodeDataChanged

而ZK内部的写事件与所触发的watcher的对应关系如下:

**event For "/path"** **defaultWatcher** **exists ("/path")** **getData ("/path")** **getChildren ("/path")**
**EventType.None**
**EventType.NodeCreated**
**EventType.NodeDeleted** √(不正常)
**EventType.NodeDataChanged**
**EventType.NodeChildrenChanged**

综合上面两个表,我们可以总结出各种写操作可以触发哪些watcher,如下表所示:

**"/path"** **"/path/child"**
**exists** **getData** **getChildren** **exists** **getData** **getChildren**
**create("/path")** **√** **√** ** ** ** ** ** ** ** **
**delete("/path")** **√** **√** **√** ** ** ** ** ** **
**setData("/path")** **√** **√** ** ** ** ** ** ** ** **
**create("/path/child")** ** ** ** ** **√** **√** **√** ** **
**delete("/path/child")** ** ** ** ** **√** **√** **√** **√**
**setData("/path/child")** ** ** ** ** ** ** **√** **√** ** **

如果发生session close、authFail和invalid,那么所有类型的wather都会被触发 zkClient除了做了一些便捷包装之外,对watcher使用做了一点增强。比如subscribeChildChanges实际上是通过exists和getChildren关注了两个事件。这样当create("/path")时,对应path上通过getChildren注册的listener也会被调用。另外subscribeDataChanges实际上只是通过exists注册了事件。因为从上表可以看到,对于一个更新,通过exists和getData注册的watcher要么都会触发,要么都不会触发。 zkClient地址:[https://github.com/sgroschupf/zkclient](https://github.com/sgroschupf/zkclient) Maven工程中使用zkClient需要加的依赖:


二、 menagerie

menagerie基于Zookeeper实现了java.util.concurrent包的一个分布式版本。这个封装是更大粒度上对各种分布式一致性使用场景的抽象。其中最基础和常用的是一个分布式锁的实现:
org.menagerie.locks.ReentrantZkLock,通过ZooKeeper的全局有序的特性和EPHEMERAL_SEQUENTIAL类型znode的支持,实现了分布式锁。具体做法是:不同的client上每个试图获得锁的线程,都在相同的basepath下面创建一个EPHEMERAL_SEQUENTIAL的node。EPHEMERAL表示要创建的是临时znode,创建连接断开时会自动删除; SEQUENTIAL表示要自动在传入的path后面缀上一个自增的全局唯一后缀,作为最终的path。因此对不同的请求ZK会生成不同的后缀,并分别返回带了各自后缀的path给各个请求。因为ZK全局有序的特性,不管client请求怎样先后到达,在ZKServer端都会最终排好一个顺序,因此自增后缀最小的那个子节点,就对应第一个到达ZK的有效请求。然后client读取basepath下的所有子节点和ZK返回给自己的path进行比较,当发现自己创建的sequential node的后缀序号排在第一个时,就认为自己获得了锁;否则的话,就认为自己没有获得锁。这时肯定是有其他并发的并且是没有断开的client/线程先创建了node。

基于分布式锁,还实现了其他业务场景,比如leader选举:
public static void leaderElectionTest() {
ZkSessionManager zksm = new DefaultZkSessionManager(“ZK-host-ip:2181”, 5000);
LeaderElector elector = new ZkLeaderElector(“/leaderElectionTest”, zksm, Ids.OPEN_ACL_UNSAFE);
if (elector.nominateSelfForLeader()) {
System.out.println(“Try to become the leader success!”);
}
}

java.util.concurrent包下面的其他接口实现,也主要是基于ReentrantZkLock的,比如ZkHashMap实现了ConcurrentMap。具体请参见menagerie的API文档

menagerie地址:https://github.com/openUtility/menagerie
Maven工程中使用menagerie需要加的依赖:


</dependency>

本文来源于"阿里中间件团队播客",原文发表时间" 2011-07-15 "

时间: 2024-10-19 01:00:10

Zookeeper Client简介的相关文章

kafka入门:简介、使用场景、设计原理、主要配置及集群搭建

[本文转载自kafka入门:简介.使用场景.设计原理.主要配置及集群搭建] 问题导读: 1.zookeeper在kafka的作用是什么? 2.kafka中几乎不允许对消息进行"随机读写"的原因是什么? 3.kafka集群consumer和producer状态信息是如何保存的? 4.partitions设计的目的的根本原因是什么? 一.入门     1.简介     Kafka is a distributed,partitioned,replicated commit logservi

zookeeper项目使用几点小结

背景   前段时间学习了zookeeper后,在新的项目中刚好派上了用场,我在项目中主要负责分布式任务调度模块的开发,对我自己来说是个不小的挑战.   分布式的任务调度,技术上我们选择了zookeeper,具体的整个分布式任务调度的架构选择会另起一篇文章进行介绍.     本文主要是介绍自己在项目中zookeeper的一些扩展使用,希望可以对大家有所帮助.   项目中使用的zookeeper版本3.3.3,对应的文档地址: http://zookeeper.apache.org/doc/trun

Zookeeper配置Kerberos认证

关于 Hadoop 集群上配置 kerberos 以及 ldap 的过程请参考本博客以下文章: HDFS配置Kerberos认证 YARN配置Kerberos认证 Hive配置Kerberos认证 Impala配置Kerberos认证 Hadoop配置LDAP集成Kerberos 参考 使用yum安装CDH Hadoop集群 安装 hadoop 集群,集群包括三个节点,每个节点的ip.主机名和部署的组件分配如下: 192.168.56.121 cdh1 NameNode.Hive.Resourc

基于ZooKeeper的分布式锁和队列

在分布式系统中,往往需要一些分布式同步原语来做一些协同工作,上一篇文章介绍了Zookeeper的基本原理,本文介绍下基于Zookeeper的Lock和Queue的实现,主要代码都来自Zookeeper的官方recipe. 锁(Lock) 完全分布式锁是全局同步的,这意味着在任何时刻没有两个客户端会同时认为它们都拥有相同的锁,使用 Zookeeper 可以实现分布式锁,需要首先定义一个锁节点(lock root node). 需要获得锁的客户端按照以下步骤来获取锁: 保证锁节点(lock root

ZooKeeper原理及使用

&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp;   ZooKeeper是Hadoop Ecosystem中非常重要的组件,它的主要功能是为分布式系统提供一致性协调(Coordination)服务,与之对应的Google的类似服务叫 Chubby.今天这篇文章分为三个部分来介绍ZooKeeper,第一部分介绍ZooKeeper的基本原理,第二部分介绍ZooKeeper提供的 Client API的使用,第三部分介绍

笃行杂记之Zookeeper SessionTimeOut分析

0.前言 本文为笃行日常工作记录,烂笔头系列. 源码前面,了无秘密 - by 侯杰 近期的一个C++项目里使用了Zookeeper做服务发现,期间遇到了SessionTimeOut问题的困扰,明明通过zookeeper c client设置了超时时间,但无效. 请原谅我一开始对zookeeper不熟悉.最终通过分析源码了解到SessionTimeOut最终的确定是一个协商的过程,而不是简单的配置生效. 在这里记录下Session超时时间的有关分析,基于zookeeper 3.4.8 1.zook

zookeeper学习记录三(session,watcher,persit机制)

背景 继续前面的zookeeper学习的专题,这次主要是结合项目中遇到的一些问题,进一步学习了下zookeeper的一些内部机制.   针对以下几个问题: 1. zk是否可以保证watcher事件不丢失? 2. zk的EPHEMERAL节点的自动过期时间?  3. zk的如何保证节点数据不丢失?   如果你已经非常清楚这以上的几个问题,看官们可以不用往下看了.  persit机制 zookeeper中的persit机制主要是通过本地disk进行持久化,在本地disk上会有个memory数据对象保

zooKeeper在weblogic下的bug

因为项目中需要使用分布式配置管理,所以使用了ZooKeeper,ZooKeeper的客户端使用的是zookeeper-3.4.5.jar原来使用的2.3.3版本,后来升级到了2.4.5升级版本,在本地调试总是正确的,但是放置到weblogic下就不行了,发现在weblogic10下竟然无法使用一直报错:  01/08 10:41:21 [WARN] ClientCnxn: Session 0x0 for server null, unexpected error, closing socket

zookeeper简单介绍

ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.名字服务.分布式同步.组服务等.ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效.功能稳定的系统提供给用户. Zookeeper是Google的Chubby一个开源的实现.是高有效和可靠的协同工作系统.Zookeeper能够用来leader选举,配置信息维护等.在一个分布式的环境中,我们需要一个Master实例或存储一些配置信息,确保文件写入的一致性