ZooKeeper快速入门

ZooKeeper快速入门

1. 概述

Zookeeper是Hadoop的一个子项目,它是分布式系统中的协调系统,可提供的服务主要有:配置服务、名字服务、分布式同步、组服务等。

它有如下的一些特点:

  • 简单

Zookeeper的核心是一个精简的文件系统,它支持一些简单的操作和一些抽象操作,例如,排序和通知。

  • 丰富

     Zookeeper的原语操作是很丰富的,可实现一些协调数据结构和协议。例如,分布式队列、分布式锁和一组同级别节点中的“领导者选举”。
    
  • 高可靠

Zookeeper支持集群模式,可以很容易的解决单点故障问题。

  • 松耦合交互

不同进程间的交互不需要了解彼此,甚至可以不必同时存在,某进程在zookeeper中留下消息后,该进程结束后其它进程还可以读这条消息。

  • 资源库

     Zookeeper实现了一个关于通用协调模式的开源共享存储库,能使开发者免于编写这类通用协议。
    

2. ZooKeeper的安装

  • 独立模式安装

Zookeeper的运行环境是需要java的,建议安装oracle的java6.

可去官网下载一个稳定的版本,然后进行安装:http://zookeeper.apache.org/

解压后在zookeeper的conf目录下创建配置文件zoo.cfg,里面的配置信息可参考统计目录下的zoo_sample.cfg文件,我们这里配置为:

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;">tickTime=2000 initLimit=10 syncLimit=5 dataDir=/opt/zookeeper-data/ clientPort=2181</pre>

tickTime****:指定了ZooKeeper的基本时间单位(以毫秒为单位);

initLimit****:指定了启动zookeeper时,zookeeper实例中的随从实例同步到领导实例的初始化连接时间限制,超出时间限制则连接失败(以tickTime为时间单位);

syncLimit****:指定了zookeeper正常运行时,主从节点之间同步数据的时间限制,若超过这个时间限制,那么随从实例将会被丢弃;

dataDir****:zookeeper存放数据的目录;

clientPort****:用于连接客户端的端口。

  • 启动一个本地的ZooKeeper****实例

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;">% zkServer.sh start</pre>

检查ZooKeeper是否正在运行

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;">echo ruok | nc localhost 2181</pre>

若是正常运行的话会打印“imok”。

3. ZooKeeper监控

  • 远程JMX****配置

默认情况下,zookeeper是支持本地的jmx监控的。若需要远程监控zookeeper,则需要进行进行如下配置。

默认的配置有这么一行:

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;">ZOOMAIN="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY org.apache.zookeeper.server.quorum.QuorumPeerMain"</pre>

咱们在$JMXLOCALONLY后边添加jmx的相关参数配置:

[
复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;">ZOOMAIN="-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY -Djava.rmi.server.hostname=192.168.1.8
-Dcom.sun.management.jmxremote.port=1911
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false org.apache.zookeeper.server.quorum.QuorumPeerMain"</pre>

[
复制代码

](javascript:void(0); "复制代码")

这样就可以远程监控了,可以用jconsole.exe或jvisualvm.exe等工具对其进行监控。

  • 身份验证

这里没有配置验证信息,如果需要请参见我的博文jvisualvm****远程监控tomcathttp://www.cnblogs.com/leocook/p/jvisualvmandtomcat.html

4. Zookeeper的存储模型

Zookeeper的数据存储采用的是结构化存储,结构化存储是没有文件和目录的概念,里边的目录和文件被抽象成了节点(node),zookeeper里可以称为znode。Znode的层次结构如下图:

image

最上边的是根目录,下边分别是不同级别的子目录。

5. Zookeeper客户端的使用

  • zkCli.sh

可使用./zkCli.sh -server localhost来连接到Zookeeper服务上。

使用ls /可查看根节点下有哪些子节点,可以双击Tab键查看更多命令。

  • Java****客户端

可创建org.apache.zookeeper.ZooKeeper对象来作为zk的客户端,注意,java api里创建zk客户端是异步的,为防止在客户端还未完成创建就被使用的情况,这里可以使用同步计时器,确保zk对象创建完成再被使用。

  • C****客户端

可以使用zhandle_t指针来表示zk客户端,可用zookeeper_init方法来创建。可在ZK_HOME\src\c\src\ cli.c查看部分示例代码。

6. Zookeeper创建Znode

Znode有两种类型:短暂的和持久的。短暂的znode在创建的客户端与服务器端断开(无论是明确的断开还是故障断开)连接时,该znode都会被删除;相反,持久的znode则不会。

image

View Code

这里我们使用了同步计数器CountDownLatch,在connect方法中创建执行了zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this);之后,下边接着调用了CountDownLatch对象的await方法阻塞,因为这是zk客户端不一定已经完成了与服务端的连接,在客户端连接到服务端时会触发观察者调用process()方法,我们在方法里边判断一下触发事件的类型,完成连接后计数器减一,connect方法中解除阻塞。

还有两个地方需要注意:这里创建的znode的访问权限是open的,且该znode是持久化存储的。

测试类如下:

[
复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;">public class CreateGroupTest { private static String hosts = "192.168.1.8"; private static String groupName = "zoo"; private CreateGroup createGroup = null; /** * init
* @throws InterruptedException
* @throws KeeperException
* @throws IOException */ @Before public void init() throws KeeperException, InterruptedException, IOException {
createGroup = new CreateGroup();
createGroup.connect(hosts);
}

@Test public void testCreateGroup() throws KeeperException, InterruptedException {
    createGroup.create(groupName);
} /** * 销毁资源 */ @After public void destroy() { try {
        createGroup.close();
        createGroup = null;
        System.gc();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

}</pre>

[
复制代码

](javascript:void(0); "复制代码")

由于zk对象的创建和销毁代码是可以复用的,所以这里我们把它分装成了接口:

image

View Code

7. Zookeeper删除Znode

[
复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;">/** * 删除分组

  • @author leo
  • */
    public class DeleteGroup extends ConnectionWatcher { public void delete(String groupName) {
    String path = "/" + groupName; try {
    List<String> children = zk.getChildren(path, false); for(String child : children){
    zk.delete(path + "/" + child, -1);
    }
    zk.delete(path, -1);//版本号为-1,
    } catch (KeeperException e) {
    e.printStackTrace();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }</pre>

[
复制代码

](javascript:void(0); "复制代码")

zk.delete(path,version)方法的第二个参数是znode版本号,如果提供的版本号和znode版本号一致才会删除这个znode,这样可以检测出对znode的修改冲突。通过将版本号设置为-1,可以绕过这个版本检测机制,无论znode的版本号是什么,都会直接将其删除。

测试类:

image

View Code

8. Zookeeper的相关操作

ZooKeeper中共有9中操作:

create:创建一个znode

delete:删除一个znode

exists:测试一个znode

getACL,setACL:获取/设置一个znode的ACL(权限控制)

getChildren:获取一个znode的子节点

getData,setData:获取/设置一个znode所保存的数据

sync:将客户端的znode视图与ZooKeeper同步

这里更新数据是必须要提供znode的版本号(也可以使用-1强制更新,这里可以执行前通过exists方法拿到znode的元数据Stat对象,然后从Stat对象中拿到对应的版本号信息),如果版本号不匹配,则更新会失败。因此一个更新失败的客户端可以尝试是否重试或执行其它操作。

9. ZooKeeper的API

ZooKeeper的api支持多种语言,在操作时可以选择使用同步api还是异步api。同步api一般是直接返回结果,异步api一般是通过回调来传送执行结果的,一般方法中有某参数是类AsyncCallback的内部接口,那么该方法应该就是异步调用,回调方法名为processResult。

10. 观察触发器

可以对客户端和服务器端之间的连接设置观察触发器(后边称之为zookeeper的状态观察触发器),也可以对znode设置观察触发器。

  • 状态观察器

zk的整个生命周期如下:

image

可在创建zk对象时传入一个观察器,在完成CONNECTING状态到CONNECTED状态时,观察器会触发一个事件,该触发的事件类型为NONE,通过event.getState()方法拿到事件状态为SyncConnected。有一点需要注意的就是,在zk调用close方法时不会触发任何事件,因为这类的显示调用是开发者主动执行的,属于可控的,不用使用事件通知来告知程序。这一块在下篇博文还会详细解说。

  • 设置znode****的观察器

可以在读操作exists、getChildren和getData上设置观察,在执行写操作create、delete和setData将会触发观察事件,当然,在执行写的操作时,也可以选择是否触发znode上设置的观察器,具体可查看相关的api。

当观察的znode****被创建、删除或其数据被更新时,设置在exists上的观察将会被触发;

当观察的znode****被删除或数据被更新时,设置在getData上的观察将会被触发;

当观察的znode****的子节点被创建、删除或znode****自身被删除时,设置在getChildren上的观察将会被触发,可通过观察事件的类型来判断被删除的是znode还是它的子节点。

image

对于NodeCreatedNodeDeleted根据路径就能发现是哪个znode被写;对于NodeChildrenChanged可根据getChildren来获取新的子节点列表。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容