[转帖]了解ZooKeeper_Hadoop,ERP及大数据讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Hadoop,ERP及大数据讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 5080 | 回复: 0   主题: [转帖]了解ZooKeeper        上一篇   下一篇 
yr
注册用户
等级:少校
经验:1085
发帖:5
精华:0
注册:2015-1-19
状态:离线
发送短消息息给yr 加好友    发送短消息息给yr 发消息
发表于: IP:您无权察看 2015-1-30 17:49:03 | [全部帖] [楼主帖] 楼主

1.1. 概述

    ZooKeeper是Apache

在很多云计算项目中

的

一个,与

Hadoop

密切相关,这种情况导致我一开始认为

ZooKeeper

的

搭建需要

Hadoop

项目作为支持,但是最后发现完全不需要,它是可以单独运行

的

一个项目。

     在网上看

到

了一个很不错

的

关于ZooKeeper

的

介绍: 顾名思义动物园管理员,他是拿来管大象

(Hadoop) 

、 蜜蜂

(Hive) 

、 小猪

(Pig)  

的

管理员, 

Apache Hbase

和 

Apache Solr 

以及

LinkedIn sensei  

等项目中都采用

到

了 

Zookeeper。ZooKeeper

是一个分布式

的

,开放源码

的

分布式应用程序协调服务,

ZooKeeper

是以

Fast Paxos

算法为基础,实现同步服务,配置维护和命名服务等分布式应用。

     从介绍可以看出,ZooKeeper

更倾向于

对

大型应用

的

协同维护管理工作。

IBM

则给出了

IBM

对

ZooKeeper

的

认知: 

Zookeeper 

分布式服务框架是 

Apache Hadoop 

的

一个子项目,它主要是用来解决分布式应用中经常遇

到

的

一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项

的

管理等。

    总之,我认为它

的

核心词就是一个单词,协调。

1.2. ZooKeeper

的

特征

     在Hadoop

权威指南中看

到

了关于

ZooKeeper

的

一些核心特征,阅读之后感觉总结

的

甚是精辟,在这里引用并总结。

1.2.1. 简易

    ZooKeeper

的

最重要核心就是一个精简文件系统,提供一些简单

的

操作

以及

附加

的

抽象(例如排序和通知)。

1.2.2. 易表达

    ZooKeeper

的

原型是一个丰富

的

集合,它们是一些已建好

的

块,可以用来构建大型

的

协作数据结构和协议,例如:分布式队列、分布式锁

以及

一组

对

等体

的

选举。

1.2.3. 高可用性

     ZooKeeper运行在一些集群上,被设计成可用性较高

的

,因此应用程序可以依赖它。ZooKeeper

可以帮助你

的

系统避免单点故障,从而建立一个可靠

的

应用程序。

1.2.4. 松散耦合

     ZooKeeper

的

交互支持参与者之间并不了解

对

方。例如:ZooKeeper可以被当做一种公共

的

机制,使得进程彼此不知道

对

方

的

存在也可以相互发现并且交互,

对

等方可能甚至不是同步

的

。

     这一特点我感觉最能体现在集群

的

部署启动过程中。像Hadoop

当把配置文件写好之后,然后运行启动脚本,则

251,241,242

中作为集群

的

虚拟机是同步启动

的

,也就是

DataNode,NameNode,TaskTracker,

以及

JobTracker

的

启动并运行时在一次启动过程中启动

的

,就是运行一次启动脚本文件,则都启动起来。但是

ZooKeeper

的

启动过程却不是这样

的

。我在

251,241,242

部署了

ZooKeeper

集群,并进行启动,则启动

的

过程是这样

的

:首先

ssh

到

251

然后启动,这时候

251

的

集群节点启动起来,但是控制台一直报错,大概

的

含义就是没有检测

到

其他两个结点。接着分别ssh

到

241,242

,分别启动集群中

的

剩下

的

结点,当

241启动起来时,回

到

251

查看,发现报错

的

信息减少,意思是只差一个结点。当

251,241,242

三台服务器

的

结点全部启动起来,则三台

的

服务器

的

控制台打印出正常

的

信息。

1.2.5. ZooKeeper是一个库

    ZooKeeper提供了一个开源

的

、共享

的

执行存储,

以及

通用协作

的

方法,分担了每个程序员写通用协议

的

负担。随着时间

的

推移,人们可以增加和改进这个库来满足自己

的

需求。

1.3. Zookeeper基本知识

     在这一小结,我介绍关于ZooKeeper

的

一些基本理论知识,以便

对

ZooKeeper

有一个基本感性

的

认识吧,由于学习

的

时间不长,有些

的

认识可能是比较片面

的

,之后如果有了更深层次

的

认识,会补充于之后

的

月总结中。

1.3.1. 层次化

的

名字空间

    ZooKeeper

的

整个名字空间

的

结构是层次化

的

,和一般

的

Linux

文件系统结构非常相似,一颗很大

的

树。这也就是

ZooKeeper

的

数据结构情况。名字空间

的

层次由斜杠

/

来进行分割,在名称空间里面

的

每一个结点

的

名字空间唯一由这个结点

的

路径来确定。

     每一个节点拥有自身

的

一些信息,包括:数据、数据长度、创建时间、修改时间等等。从这样一类既含有数据,又作为路径表标示

的

节点

的

特点

中,

可以看出,ZooKeeper

的

节点既可以被看做是一个文件,又可以被看做是一个目录,它同时具有二者

的

特点。为了便于表达,今后我们将

使用

Znode

来表示所讨论

的

ZooKeeper

节点。

1.3.2. Znode

    Znode维护着数据、ACL(access control list,访问控制列表)、时间戳等交换版本号等数据结构,它

通过

对

这些数据

的

管理来让缓存生效并且令协调更新。每当Znode

中

的

数据更新后它所维护

的

版本号将增加,这非常类似于数据库中计数器时间戳

的

操作方式。

另外Znode

还具有原子性操作

的

特点:命名空间

中,

每一个

Znode

的

数据将被原子地读写。读操作将读取与

Znode

相关

的

所有数据,写操作将替换掉所有

的

数据。除此之外,每一个节点都有一个访问控制列表,这个访问控制列表规定了用户操作

的

权限。

    ZooKeeper中同样存在临时节点。这些节点与session

同时存在,当

session

生命周期结束,这些临时节点也将被删除。临时节点在某些场合也发挥着非常重要

的

作用。

1.3.3. Watch机制

     Watch机制就和单词本身

的

意思一样,看。看什么?具体来讲就是某一个或者一些Znode

的

变化。官方给出

的

定义:一个

Watch

事件是一个一次性

的

触发器,当被设置了

Watch

的

数据发生了改变

的

时候,则服务器将这个改变发送给设置了

Watch

的

客户端,以便通知它们。

Watch机制主要有以下三个特点:

1 一次性

的

触发器(one-time trigger)

     当数据改变

的

时候,那么一个Watch事件会产生并且被发送

到

客户端中。但是客户端只会收

到

一次这样

的

通知

,如果

以后这个数据再次发生改变

的

时候,之前设置Watch

的

客户端将不会再次收

到

改变

的

通知,因为Watch

机制规定了它是一个一次性

的

触发器。

2 发送给客户端

     这个表明了Watch

的

通知事件是从服务器发送给客户端

的

,是异步

的

,这就表明不同

的

客户端收

到

的

Watch

的

时间可能不同,但是

ZooKeeper有保证:当一个客户端在看

到

Watch事件之前是不会看

到

结点数据

的

变化

的

。例如:A=3

,此时在上面设置了一次

Watch

,如果

A

突然变成

4了,那么客户端会先收

到

Watch事件

的

通知,然后才会看

到

A=4。

3被设置Watch

的

数据

     这表明了一个结点可以变换

的

不同方式。一个Znode变化方式有两种,结点本身数据

的

变化

以及

结点孩子

的

变化。因此Watch

也可以设置为这个

Znode

的

结点数据,当然也可以设置为

Znode

结点孩子。

1.3.4. ACL访问控制列表

    这是另外一个和Linux

操作系统非常相似

的

地方,

ZooKeeper

使用

ACL来控制

对

旗下Znode

结点们

的

访问。

ACL

的

实现和

Linux文件系统

的

访问权限十分类似:它

通过

设置

权限为来表明是否允许

对

一个结点

的

相关内容

的

改变。

     但是与传统Linux

机制不太相同,一个结点

的

数据没有类似“拥有者,组用户,其他用户”

的

概念,在

ZooKeeper

中,

ACL

通过

设置

ID

以及

与其关联

的

权限来完成访问控制

的

。ACL

的

权限组成语法是:

(scheme:expression, perms)


前者表明设置

的

ID

,逗号后面表示

的

是

ID

相关

的

权限,例如:

(ip:172.16.16.1, READ)


指明了IP

地址为如上

的

用户

的

权限为只读。

以下列举以下ACL

所具有

的

权限

CREATE:表明你可以创建一个Znode

的

子结点。

READ:你可以得

到

这个结点

的

数据

以及

列举该结点

的

子结点情况。

WRITE:设置一个结点

的

数据。

DELETE:可以删除一个结点

ADMIN:

对

一个结点设置权限。

1.4. ZooKeeper

的

部署

以及

简单

使用


     要想

使用

ZooKeeper

,首先就要把它部署在服务器上跑起来,就想

Apache,Tomcat,FtpServer

等服务器一样。

ZooKeeper

的

部署方式主要有三种,单机模式、伪集群模式、集群模式。其实剩下

的

两种模式都是集群模式

的

特殊情况。

1.4.1. 基本

的

环境变量配置

    Java大型

的

项目

中,

环境变量

的

配置很重要

,如果

没有很好

的

配置环境变量

的

话,甚至项目连启动都是难事。

export ZOOKEEPER_HOME=/home/zookeeper-3.3.3
export PATH=$PATH:$ZOOKEEPER_HOME/bin:$ZOOKEEPER_HOME/conf


    1.4.2. ZooKeeper

的

单机模式部署

ZooKeeper

的

单机模式通常是用来快速测试客户端应用程序

的

,在实际过程中不可能是单机模式。单机模式

的

配置也比较简单。

l 编写配置文件zoo.cfg

    zookeeper-3.3.3/conf文件夹下面就是要编写配置文件

的

位置了。在文件夹下面新建一个文件zoo.cfg。ZooKeeper

的

运行默认是读取

zoo.cfg

文件里面

的

内容

的

。以下是一个最简单

的

配置文件

的

样例:

tickTime=2000
dataDir=/var/zookeeper
clientPort=2181


    在这个文件

中,

我们需要指定 dataDir 

的

值,

它指向了一个目录,这个目录在开始

的

时候需要为空。下面是每个参数

的

含义:

tickTime :基本事件单元,以毫秒为单位。这个时间是作为 Zookeeper 

服务器之间或客户端与服务器之间维持心跳

的

时间间隔,也就是每个 

tickTime 

时间就会发送一个心跳。 

dataDir :存储内存中数据库快照

的

位置,顾名思义就是 Zookeeper 

保存数据

的

目录,默认情况下,

Zookeeper 

将写数据

的

日志文件也保存在这个目录里。 

clientPort :这个端口就是客户端连接 Zookeeper 

服务器

的

端口,

Zookeeper 

会监听这个端口,接受客户端

的

访问请求。

   

使用

单机模式时用户需要注意:这种配置方式下没有 ZooKeeper 

副本,所以如果 

ZooKeeper 

服务器出现故障, 

ZooKeeper 

服务将会停止。

l 执行运行脚本

    在zookeeper-3.3.3/bin

文件夹下面运行

zkServer.sh

即可,运行完毕之后则

ZooKeeper

服务变启动起来。

./zkServer.sh start


    脚本默认调用zoo.cfg

里面

的

配置,因此程序正常启动。

1.4.3. ZooKeeper

的

集群模式部署

     ZooKeeper

的

集群模式下,多个Zookeeper

服务器在工作前会选举出一个

Leader

,在接下来

的

工作中这个被选举出来

的

Leader

死了,而剩下

的

Zookeeper

服务器会知道这个

Leader

死掉了,在活着

的

Zookeeper

集群中会继续选出一个

Leader

,选举出

Leader

的

目

的

是为了可以在分布式

的

环境中保证数据

的

一致性。

l 确认集群服务器

的

数量

     由于ZooKeeper集群

中,

会有一个Leader

负责管理和协调其他集群服务器,因此服务器

的

数量通常都是单数,例如

3,5,7...

等,这样

2n+1

的

数量

的

服务器就可以允许最多

n

台服务器

的

失效。

l 编写配置文件

配置文件需要在每台服务器中都要编写,以下是一个配置文件

的

样本:

# Filename zoo.cfg
tickTime=2000
dataDir=/var/zookeeper/
clientPort=2181
initLimit=5
syncLimit=2
server.1=202.115.36.251:2888:3888
server.2=202.115.36.241:2888:3888
server.3=202.115.36.242:2888:3888


    initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说

的

客户端不是用户连接 Zookeeper 服务器

的

客户端,而是 
Zookeeper 服务器集群中连接

到

 
Leader 

的

 
Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 10 个心跳

的

时间(也就是 
tickTime)长度后 Zookeeper 服务器还没有收

到

客户端

的

返回信息,那么表明这个客户端连接失败。总

的

时间长度就是 
5*2000=10 秒。

    syncLimit:这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 

的

时间长度,总

的

时间长度就是 2*2000=4 秒 

    server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器

的

 ip 地址;C 表示

的

是这个服务器与集群中

的

 
Leader 服务器交换信息

的

端口;
D 表示

的

是万一集群中

的

 
Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新

的

 
Leader,而这个端口就是用来执行选举时服务器相互通信

的

端口。如果是伪集群

的

配置方式,由于 
B 都是一样,所以不同

的

 
Zookeeper 实例通信端口号不能一样,所以要给它们分配不同

的

端口号。

l 创建myid

文件

    除了修改 zoo.cfg 

配置文件,集群模式下还要配置一个文件 

myid

,这个文件在 

dataDir 

目录下,这个文件里面就只有一个数据就是 

A 

的

值,

Zookeeper 启动时会读取这个文件,拿

到

里面

的

数据与 zoo.cfg 里面

的

配置信息比较从而判断

到

底是那个 server。

l 执行运行脚本

     和单机模式下

的

运行方式基本相同,值得注意

的

地方就是要分别在不同服务器上执行一次,例如分别在251,241,242

上运行:

./zkServer.sh start


这样才能使得整个集群启动起来。

1.4.4. ZooKeeper

的

集群伪分布

    其实在企业中式不会存在

的

,另外为了测试一个客户端程序也没有必要存在,只有在物质条件比较匮乏

的

条件下才会存在

的

模式。

集群伪分布模式就是在单机下模拟集群

的

ZooKeeper

服务,在一台机器上面有多个

ZooKeeper

的

JVM

同时运行。

l 确认集群伪服务器

的

数量

    2n+1,和之前

的

集群分布相同。

l 编写配置文件

    在/conf

文件夹新建三个配置文件,

zoo1.cfg,zoo2.cfg

以及

zoo3.cfg

。配置文件分别如下编写:

Zoo1.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/root/hadoop-0.20.2/zookeeper-3.3.1/d_1
clientPort=2181
server.1=localhost:2887:3887
server.2=localhost:2888:3888
server.3=localhost:2889:3889
Zoo2.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/root/hadoop-0.20.2/zookeeper-3.3.1/d_2
clientPort=2182
server.1=localhost:2887:3887
server.2=localhost:2888:3888
server.3=localhost:2889:3889
Zoo3.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/root/hadoop-0.20.2/zookeeper-3.3.1/d_3
clientPort=2183
server.1=localhost:2887:3887
server.2=localhost:2888:3888
server.3=localhost:2889:3889


    由于三个服务都在同一台电脑上,因此这里要保证地址

的

唯一性,因此要特别注意IP地址和端口号不要互相冲突,以免影响程序

的

正确执行。

l 创建myid

文件

    这个同集群模式部署,在各自

的

文件夹下面创建。

l 执行运行脚本

    由于所有

的

配置文件都在/conf文件夹下面,因此要执行三次,而且要加文件名

的

参数,不然会默认执行zoo.cfg

这个文件,如下:

./zkServer.sh start zoo1.cfg
./zkServer.sh start zoo2.cfg
./zkServer.sh start zoo3.cfg


执行完毕后,将完成ZooKeeper

的

集群伪分布

的

启动。

1.4.5. 

通过

ZooKeeper

命令行工具访问

ZooKeeper

     ZooKeeper命令行工具类似于Linux

的

shell

环境,不过功能肯定不及

shell啦,但是

使用

它我们可以简单

的

对

ZooKeeper

进行访问,数据创建,数据修改等操作。

当启动 ZooKeeper 服务成功之后,输入下述命令,连接

到

 ZooKeeper 

服务:

zkCli.sh –server 202.115.36.251:2181


连接成功后,系统会输出 ZooKeeper 

的

相关环境

以及

配置信息,并在屏幕输出“ Welcome to ZooKeeper 

”等信息。

命令行工具

的

一些简单操作如下:

1 )

使用

 ls 

命令来查看当前 

ZooKeeper 中所包含

的

内容:

[zk: 202.115.36.251:2181(CONNECTED) 1] ls /


2 )创建一个新

的

 znode ,

使用

 create /zk myData 。这个命令创建了一个新

的

 znode 

节点“ 

zk ”

以及

与它关联

的

字符串:

[zk: 202.115.36.251:2181(CONNECTED) 2] create /zk "myData"


3 )我们运行 get 

命令来确认 

znode 是否包含我们所创建

的

字符串:

[zk: 202.115.36.251:2181(CONNECTED) 3] get /zk


4 )下面我们

通过

 set 命令来

对

 zk 所关联

的

字符串进行设置:

[zk: 202.115.36.251:2181(CONNECTED) 4] set /zk "zsl"


5 )下面我们将刚才创建

的

 znode 

删除:

[zk: 202.115.36.251:2181(CONNECTED) 5] delete /zk


1.4.6. 

使用

API

来访问

ZooKeeper

     API访问ZooKeeper才是客户端主要

的

使用

手段,

通过

在客户端编写丰富多彩

的

程序,来达

到

对

ZooKeeper

的

利用。这里给出一个简单

的

例子:(深入

的

还没能力给出啊,例子是从网上找

的

很清晰明了)

1. import java.io.IOException;

2.

3. import org.apache.zookeeper.CreateMode;

4. import org.apache.zookeeper.KeeperException;

5. import org.apache.zookeeper.Watcher;

6. import org.apache.zookeeper.ZooDefs.Ids;

7. import org.apache.zookeeper.ZooKeeper;

8.

9. public class demo {

10. // 会话超时时间,设置为与系统默认时间一致
11. private static final int SESSION_TIMEOUT=30000;
12.
13. // 创建 ZooKeeper 实例
14. ZooKeeper zk;
15.
16. // 创建 Watcher 实例
17. Watcher wh=new Watcher(){
      18. public void process(org.apache.zookeeper.WatchedEvent event)
      19. {
            20. System.out.println(event.toString());
      21. }
22. };
23.
24. // 初始化 ZooKeeper 实例
25. private void createZKInstance() throws IOException
26. {
      27. zk=new ZooKeeper("localhost:2181",demo.SESSION_TIMEOUT,this.wh);
      28.
29. }
30.
31. private void ZKOperations() throws IOException,InterruptedException,KeeperException
32. {
      33. System.out.println("\n1. 创建 ZooKeeper 节点 (znode : zoo2, 数据: myData2 ,权限: OPEN_ACL_UNSAFE ,节点类型: Persistent");
      34. zk.create("/zoo2","myData2".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
      35.
      36. System.out.println("\n2. 查看是否创建成功: ");
      37. System.out.println(new String(zk.getData("/zoo2",false,null)));
      38.
      39. System.out.println("\n3. 修改节点数据 ");
      40. zk.setData("/zoo2", "shenlan211314".getBytes(), -1);
      41.
      42. System.out.println("\n4. 查看是否修改成功: ");
      43. System.out.println(new String(zk.getData("/zoo2", false, null)));
      44.
      45. System.out.println("\n5. 删除节点 ");
      46. zk.delete("/zoo2", -1);
      47.
      48. System.out.println("\n6. 查看节点是否被删除: ");
      49. System.out.println(" 节点状态: ["+zk.exists("/zoo2", false)+"]");
50. }
51.
52. private void ZKClose() throws InterruptedException
53. {
      54. zk.close();
55. }
56.
57. public static void main(String[] args) throws IOException,InterruptedException,KeeperException {
      58. demo dm=new demo();
      59. dm.createZKInstance( );
      60. dm.ZKOperations();
      61. dm.ZKClose();
62. }
63.}


    此类包含两个主要

的

 ZooKeeper 函数,分别为 createZKInstance ()和 ZKOperations ()。其中 createZKInstance ()函数负责

对

 ZooKeeper 实例 zk 进行初始化。 ZooKeeper 类有两个构造函数,我们这里

使用

  “
 ZooKeeper ( String connectString, , int sessionTimeout, , Watcher watcher )”

对

其进行初始化。因此,我们需要提供初始化所需

的

,连接字符串信息,会话超时时间,

以及

一个
 watcher 实例。 17 行

到

 23 行代码,是程序所构造

的

一个
 watcher 实例,它能够输出所发生

的

事件。

    ZKOperations ()函数是我们所定义

的

对

节点

的

一系列操作。它包括:创建
 ZooKeeper 节点( 33 行

到

 34 行代码)、查看节点( 36 行

到

 37 行代码)、修改节点数据( 39 行

到

 40 行代码)、查看修改后节点数据( 42 行

到

 43 行代码)、删除节点( 45 行

到

 46 行代码)、查看节点是否存在( 48 行

到

 49 行代码)。另外,需要注意

的

是:在创建节点

的

时候,需要提供节点

的

名称、数据、权限

以及

节点类型。此外,

使用

 exists 函数时

,如果

节点不存在将返回一

个 null 值。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论