ZooKeeper 笔记

ZooKeeper笔记(1)安装部署及helloworld

先给一堆学习文档,方便以后查看

官网文档地址大全:

OverView(概述)

http://zookeeper.apache.org/doc/r3.4.6/zookeeperOver.html

GettingStarted(开始入门)

http://zookeeper.apache.org/doc/r3.4.6/zookeeperStarted.html

Tutorial(教程)

http://zookeeper.apache.org/doc/r3.4.6/zookeeperTutorial.html

JavaExample(Java示例)

http://zookeeper.apache.org/doc/r3.4.6/javaExample.html

Programmer'sGuide(开发人员指南)

http://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html

RecipesandSolutions(技巧及解决方案)

http://zookeeper.apache.org/doc/r3.4.6/recipes.html

3.4.6APIonline(在线API速查)

http://zookeeper.apache.org/doc/r3.4.6/api/index.html

另外推荐园友sunddenly的zookeeper系列

http://www.cnblogs.com/sunddenly/category/620563.html

一、安装部署

本文在一台机器上模拟3个zkserver的集群安装

1.1下载解压

解压到3个目录(模拟3台zkserver):

/home/hadoop/zookeeper-1

/home/hadoop/zookeeper-2

/home/hadoop/zookeeper-3

1.2创建每个目录下conf/zoo.cfg配置文件

/home/hadoop/zookeeper-1/conf/zoo.cfg内容如下:

复制代码

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/home/hadoop/tmp/zk1/data

dataLogDir=/home/hadoop/tmp/zk1/log

clientPort=2181

server.1=localhost:2287:3387

server.2=localhost:2288:3388

server.3=localhost:2289:3389

复制代码

/home/hadoop/zookeeper-2/conf/zoo.cfg内容如下:

复制代码

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/home/hadoop/tmp/zk2/data

dataLogDir=/home/hadoop/tmp/zk2/log

clientPort=2182

server.1=localhost:2287:3387

server.2=localhost:2288:3388

server.3=localhost:2289:3389

复制代码

/home/hadoop/zookeeper-3/conf/zoo.cfg内容如下:

复制代码

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/home/hadoop/tmp/zk3/data

dataLogDir=/home/hadoop/tmp/zk3/log

clientPort=2183

server.1=localhost:2287:3387

server.2=localhost:2288:3388

server.3=localhost:2289:3389

复制代码

注:因为是在一台机器上模拟集群,所以端口不能重复,这里用2181~2183,2287~2289,以及3387~3389相互错开。另外每个zk的instance,都需要设置独立的数据存储目录、日志存储目录,所以dataDir、dataLogDir这二个节点对应的目录,需要手动先创建好。

另外还有一个灰常关键的设置,在每个zkserver配置文件的dataDir所对应的目录下,必须创建一个名为myid的文件,其中的内容必须与zoo.cfg中server.x中的x相同,即:

/home/hadoop/tmp/zk1/data/myid中的内容为1,对应server.1中的1

/home/hadoop/tmp/zk2/data/myid中的内容为2,对应server.2中的2

/home/hadoop/tmp/zk3/data/myid中的内容为3,对应server.3中的3

生产环境中,分布式集群部署的步骤与上面基本相同,只不过因为各zkserver分布在不同的机器,上述配置文件中的localhost换成各服务器的真实Ip即可。分布在不同的机器后,不存在端口冲突问题,可以让每个服务器的zk均采用相同的端口,这样管理起来比较方便。

1.3启动验证

/home/hadoop/zookeeper-1/bin/zkServer.shstart

/home/hadoop/zookeeper-2/bin/zkServer.shstart

/home/hadoop/zookeeper-3/bin/zkServer.shstart

启用成功后,输入jps看下进程

20351ZooKeeperMain

20791QuorumPeerMain

20822QuorumPeerMain

20865QuorumPeerMain

应该至少能看到以上几个进程。

可以启动客户端测试下:

bin/zkCli.sh-serverlocalhost:2181

(注:如果是远程连接,把localhost换成指定的IP即可)

成功后,应该会进到提示符下,类似下面这样:

[zk:localhost:2181(CONNECTED)0]

然后,就可以用一些基础命令,比如ls,create,delete,get来测试了(关于这些命令,大家可以查看文档),特别提一个很有用的命令rmr用来递归删除某个节点及其所有子节点

二、java与zk的连接示例

2.1maven项目的pom.xml中先添加以下依赖项

复制代码

<!--zk-->

<dependency>

<groupId>org.apache.zookeeper</groupId>

<artifactId>zookeeper</artifactId>

<version>3.4.6</version>

</dependency>

复制代码

2.2最基本的示例程序

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

packageyjmyzz;

importjava.io.IOException;

importorg.apache.zookeeper.*;

importorg.apache.zookeeper.data.Stat;

publicclassZooKeeperHello{

publicstaticvoidmain(String[]args)throwsIOException,InterruptedException,KeeperException{

ZooKeeperzk=newZooKeeper("172.28.20.102:2181",300000,newDemoWatcher());//连接zkserver

Stringnode="/app1";

Statstat=zk.exists(node,false);//检测/app1是否存在

if(stat==null){

//创建节点

StringcreateResult=zk.create(node,"test".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);

System.out.println(createResult);

}

//获取节点的值

byte[]b=zk.getData(node,false,stat);

System.out.println(newString(b));

zk.close();

}

staticclassDemoWatcherimplementsWatcher{

@Override

publicvoidprocess(WatchedEventevent){

System.out.println("----------->");

System.out.println("path:"+event.getPath());

System.out.println("type:"+event.getType());

System.out.println("stat:"+event.getState());

System.out.println("<-----------");

}

}

}

2.3与zk集群的连接

zk的优点之一,就是高可用性,上面的代码连接的是单台zkserver,如果这台server挂了,自然代码就会出错,事实上zk的API考虑到了这一点,把连接代码改成下面这样:

ZooKeeperzk=newZooKeeper("172.28.20.102:2181,172.28.20.102:2182,172.28.20.102:2183",300000,newDemoWatcher());//连接zkserver

即:IP1:port1,IP2:port2,IP3:port3...用这种方式连接集群就行了,只要有超过半数的zkserver还活着,应用一般就没问题。但是也有一种极罕见的情况,比如这行代码执行时,刚初始化完成,正准备连接ip1时,因为网络故障ip1对应的server挂了,仍然会报错(此时,zk还来不及选出新leader),这个问题详见:http://segmentfault.com/q/1010000002506725/a-1020000002507402,参考该文的做法,改成:

复制代码

1ZooKeeperzk=newZooKeeper("172.28.20.102:2181,172.28.20.102:2182,172.28.20.102:2183",300000,newDemoWatcher());//连接zkserver

2if(!zk.getState().equals(ZooKeeper.States.CONNECTED)){

3while(true){

4if(zk.getState().equals(ZooKeeper.States.CONNECTED)){

5break;

6}

7try{

8TimeUnit.SECONDS.sleep(5);

9}catch(InterruptedExceptione){

10e.printStackTrace();

11}

12}

13}

复制代码

但是这样代码未免太冗长,建议用开源的zkClient,官方地址:https://github.com/sgroschupf/zkclient,使用方法很简单:

复制代码

<!--zkclient-->

<dependency>

<groupId>com.github.sgroschupf</groupId>

<artifactId>zkclient</artifactId>

<version>0.1</version>

</dependency>

复制代码

pom.xml先加这一坨,然后这样用:

复制代码

1@Test

2publicvoidtestZkClient(){

3ZkClientzkClient=newZkClient("172.28.20.102:2181,172.28.20.102:2182,172.28.20.102:2183");

4Stringnode="/app2";

5if(!zkClient.exists(node)){

6zkClient.createPersistent(node,"hellozk");

7}

8System.out.println(zkClient.readData(node));

9}

相关推荐