Zookeeper学习笔记

本文是对Zookeeper组件基础知识的一个学习总结,包含如下章节内容:

  • Zookeeper是什么
  • Zk文件系统
  • Zk的观察机制
  • Zk的设计思路
  • 安装和运行
  • 命令行程序

一、Zookeeper是什么

ZooKeeper(下面简称Zk)是一个开源的分布式协调服务组件,它为分布式应用提供了高效且可靠的分布式协调服务,提供了诸如统一命名空间服务,配置服务和分布式锁等分布式基础服务。

Zk是一个独立的组件,不依赖其它服务。它本身就是一个分布式应用。作为分布式应用,分为Server(服务器) 和 Client(客户端) 两部分。作为Zk的使用者,可以使用Zk组件提供的客户端(命令行程序)或自己利用Zk提供的api编写客户端程序来访问Zk服务器。

hadoop生态圈中很多分布式组件都使用Zk来作为分布式协调服务,如hdfs HA(High Availability), yarn HA, hbase,kafka等,从这角度看,hbase等就是Zk服务的客户端。当然,也可以使用Zk提供的服务来开发自己的分布式应用程序。

二、Zk文件系统

Zk服务的核心是一个精简的文件系统,类似linux文件系统的树形层次结构,与文件系统节点分目录和文件不同,Zk文件系统中的节点统一称为znode。如下图所示:


Zk文件系统的信息会保存在内存中(以加快读取的速度),同时会进行持久化。

(一)znode的概念

znode通过路径被引用,类似linux文件系统的路径。根节点用/表示,其余节点从/开始加上各层节点的名称,如/zoo/duck。但是与文件系统路径不同,znode没有相对路径的概念,每个节点都以绝对路径标识。

znode既可以作为保存数据的容器(如同文件),也可以作为保存其它znode的容器(如目录)。znode除了可以保存数据外(保存的数据不能太大,一个znode存储的数据被限制在1M以内),znode本身就是一个数据结构,其中的信息称为元数据(如创建时间、子节点信息、版本信息、ACL信息等)。

(二)znode的操作

znode支持如下9种基本操作:

  • create:创建znode
  • delete:删除znode
  • exists:测试一个znode是否存在并且查询它的元数据
  • getChildren:获取一个znode的子节点列表
  • setACL:设置znode的ACL
  • getACL:获取znode的ACL
  • setData:设置znode所保存的数据
  • getData:获取znode所保存的数据
  • sync:将客户端的znode视图与zk服务器同步

(三)znode的类型

znode可分为短暂的(或叫临时的)和持久的。所谓短暂znode,是指创建该节点的客户端会话结束后,该节点会被自动删除。而持久znode的生存期与创建它的客户端会话无关,如果要删除,需要显示的执行命令删除。注意,短暂znode不可以有子节点。

顺序znode:指znode的名称中包含顺序号。当我们创建一个顺序znode时,框架会自动在指定的名称之后附加一个单调递增的计数器值(由父节点维护),并且保证这个计数器值是唯一的。注意,顺序znode可以是持久的,或短暂的。

(四)znode的版本信息

znode有版本信息,对于每个znode来说,均存在三个版本号:

  1. dataVersion
    数据版本号,每次对节点进行set操作,dataVersion的值都会增加1(即使设置的是相同的数据),初始值为0。

  2. cversion
    子节点的版本号。当znode的子节点有变化时,cversion 的值就会增加1,初始值为0。

  3. aclVersion
    ACL的版本号。

下面以dataVersion (数据版本号)为例来说明Zk中版本号的作用。每一个znode都有一个数据版本号,它随着每次数据变化而自增。ZooKeeper提供的一些API例如setData和delete根据版本号有条件地执行。多个客户端对同一个znode进行操作时,版本号的使用就会显得尤为重要。例如,假设客户端C1对znode /config写入一些配置信息,如果另一个客户端C2同时更新了这个znode,此时C1的版本号已经过期,C1调用setData一定不会成功。这正是版本机制有效避免了数据更新时出现的先后顺序问题。在这个例子中,C1在写入数据时使用的版本号无法匹配,使得操作失败。因此使用版本号可用来阻止并行操作的不一致性。

(五)znode的ACL列表

每个znode都有一个ACL(权限控制列表),用于决定哪个客户端可以对它执行何种操作,也就是说一种权限控制的方式。 znode的ACL列表可以在创建时指定,也可以后续重新设置。如果不加设置,默认所有客户端可以对znode进行任何操作。关于ACL的更详细信息本文不再介绍。

三、Zk的观察机制

当znode的发生变化时,Zk提供一种观察(watch)机制可以让希望获取这个变化信息的客户端得到通知。当一个客户端对一个节点设置了观察,如果该节点发生变化(如被删除、设置数据、添加/删除子节点等),Zk框架会通知设置了观察的客户端。

注意,节点上设置了观察,当节点发生变化后,只会通知一次。如果想再次获取通知,需要重新设置。

四、Zk的设计思路

在集群环境下,Zk通过复制来实现高可用性,只要集群环境下的超过一半机器处于可用状态,它就能提供服务。比如一个集群有5个节点,任意2台机器出现问题,但因为还有3台机器可用,3台超过1半,所以服务可以继续保证。如果集群是6台节点,也最多只能有2台机器出问题,因为如果有3台机器有问题,则可用的没超过一半,服务也不可用。因此,对于Zk的集群,其节点的数量通常配置为奇数个。

集群中的节点分为两种类型:领导者(leader)和跟随着(flower)。 集群中的机器通过一个选择过程来选出领导者,其它的机器就作为跟随者。如果领导者出现故障,其它机器就会选出一个新的领导者。随后,如果之前的领导者恢复,则会成为一个跟随者。

Zk客户端可以连接到任意一台Zk服务器,但是所有的写请求都会被转发给领导者,再由领导者将更新广播给跟随者,当半数以上的跟随者已经将修改持久化之后,领导者才会提交这个更新,然后客户端才会收到一个更新成功的响应。

下面示意图可以简单说明上面描述的内容:


(摘自hadoop权威指南一书)

五、安装和运行

Zk既可以运行在windows系统下,也可以运行在liunux系统下。它有两种不同的运行模式。一种是独立模式,即只有一个Zk服务器,这种模式只适合开发测试环境,不能保证高可用性和可恢复性。另一种是复制模式,运行在集群环境下,至少需要三台机器(启动3个Zk服务)。在本文中,我们使用独立模式来学习Zk的基本概念和操作。

1、下载Zookeeper,本文下载的版本是zookeeper-3.4.10.tar.gz。

将该压缩文件解压到某个目录下。

2、修改conf 下的zoo.cfg文件(如果没有就新建),增加如下的配置信息,最少的配置信息如下(假设我们采用独立模式运行Zk服务器,即只在一台机器上启动单个Zk服务),其它配置信息采用默认值。

tickTime=2000
dataDir= 本地某目录
clientPort=2181

tikeTime是超时时间设置(单位是毫秒);dataDir用于设置一个本地目录,保存Zk文件系统的持久化信息。clientPort是设置Zk服务器的端口号。

3、启动Zk服务器
启动服务器的程序位于Zk安装目录下的bin目录下,windows下的可执行程序为zkServer.cmd,linux下的可执行程序是zkServer.sh

说明:可以将bin目录加到PATH环境变量下,这样可以在任意在目录下运行服务器程序。

六、命令行程序

Zk提供了一个命令行程序,可以连接到Zk服务器,执行对znode的各种操作。该命令行程序在Zk安装目录的bin目录下,windows下的程序名叫zkCli.cmd,linux下的程序名叫zkCli.sh

如果是连接到本机的服务器,在控制台中运行上面客户端程序即可。
如果是连接到其它机器的服务器,则加上服务器ip地址和端口即可。如:zkCli.cmd/zkCli.sh -server IP地址:2181

如果一切正常,则就可以执行命令了。下面展示一些常见的命令:

1、ls命令
语法: ls 节点路径
含义:列出指定节点下的所有子节点名称
举例:

[zk: localhost:2181(CONNECTED) 0] ls /
[cluster, brokers, zookeeper, admin,  zoo]
[zk: localhost:2181(CONNECTED) 1] ls /zoo
[dd]

2、ls2命令
语法: ls2 节点路径
含义:列出指定节点下的所有子节点名称 ,以及当前节点的元数据信息,如time、version等信息
举例:

[zk: localhost:2181(CONNECTED) 2] ls2 /zoo
[dd]
cZxid = 0xf1
ctime = Mon Dec 03 17:17:41 CST 2018
mZxid = 0x126
mtime = Tue Dec 04 20:03:09 CST 2018
pZxid = 0x106
cversion = 3
dataVersion = 11
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 1

3、create命令
语法: create [-s] [-e] path data acl
含义:创建znode节点,其中参数path是节点的路径,data是节点存储的字符串数据,-s选项表示是创建短暂的节点,-e选项表示是创建顺序节点。
举例:

[zk: localhost:2181(CONNECTED) 8] create /zoo/newnode ""
Created /zoo/newnode
[zk: localhost:2181(CONNECTED) 9] create -e /zoo/tmpnode "hello"
Created /zoo/tmpnode
[zk: localhost:2181(CONNECTED) 10] create -s /zoo/mynode "data"
Created /zoo/mynode0000000006
[zk: localhost:2181(CONNECTED) 11] ls /zoo
[dd, tmpnode, mynode0000000006, newnode]

4、delete命令
语法:delete path [version]
含义:删除指定的节点,path为待删除节点路径。version是节点版本号,如果指定,则version值必须与待删除节点的数据版本号一致,否则无法删除。如果不指定version参数,则删除时不管版本号。如果节点下有子节点,则无法删除。
举例:

[zk: localhost:2181(CONNECTED) 17] delete /zoo/newnode 2
version No is not valid : /zoo/newnode
[zk: localhost:2181(CONNECTED) 18] delete /zoo/newnode
[zk: localhost:2181(CONNECTED) 19] ls /zoo/newnode
Node does not exist: /zoo/newnode

5、set命令
语法:set path data [version]
含义:设置znode存储的数据。path为znode路径。data为要设置的字符串内容。version是节点版本号,如果指定,则version值必须与待设置节点的数据版本号一致,否则无法设置。如果不指定version参数,则设置时不管版本号。
举例:

[zk: localhost:2181(CONNECTED) 28] set /zoo gooddata
cZxid = 0xf1
ctime = Mon Dec 03 17:17:41 CST 2018
.............

6、get命令
语法:get path [watch]
含义:获取znode存储的数据及元数据信息。如果加上watch标记,则表示该客户端对该znode进行观察。当其它客户端(或本客户端)对该znode进行变更后,该客户端会收到通知。
举例:

[zk: localhost:2181(CONNECTED) 30] get /zoo watch
gooddata
cZxid = 0xf1
ctime = Mon Dec 03 17:17:41 CST 2018
mZxid = 0x148
mtime = Thu Dec 06 10:29:37 CST 2018
pZxid = 0x145
cversion = 11
dataVersion = 14
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 8
numChildren = 3

上面例子中的get命令加上了可选项watch标记。这时如果我们打开另外一个命令行客户端,并对/zoo节点进行设置存储数据操作。会发现当前客户端会收到消息,如下面内容:

[zk: localhost:2181(CONNECTED) 30] get /zoo watch
gooddata
cZxid = 0xf1
ctime = Mon Dec 03 17:17:41 CST 2018
mZxid = 0x148
mtime = Thu Dec 06 10:29:37 CST 2018
pZxid = 0x145
cversion = 11
dataVersion = 14
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 8
numChildren = 3
[zk: localhost:2181(CONNECTED) 31]
WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/zoo

如果我们在另外一个客户端对/zoo节点进行设置存储数据操作后,再次执行set操作,会发现上面客户端不会再收到消息。这正如前面介绍,设置观察后,收到一次消息后观察不再有效,要想再次接受消息,必须重新设置。

上面介绍了zk命令行客户端的一些常见命令,还有其它一些命令(可以输入help查看所有支持的命令),这里不再一一介绍。在实际应用中,我们更多往往通过zk提供的编程API(如java api)来编写zk客户端程序,这个在后面的文章中介绍。

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

推荐阅读更多精彩内容