zookeeper学习笔记

  因最近工作中要用到zookeeper,故找来资料学习一番,为加强记忆,特做笔记如下:

  笔记内容:

  1、zookeeper背景

  2、本地微集群配置

  3、java api使用

  4、几种常见使用场景

  5、运维管理

  6、自己的理解

-----------分割线之开始正文----------------------------------------------------------------------------------------------------

一、背景

  (说实话,以下是我网上抄的,具体的理解在最后再写)ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。

二、本地伪集群配置

  就是在本地起三个zookeeper服务,模拟zookeeper集群。在本地建三个文件夹,分别叫server1、server2跟server3。每一个其中都包含data、datalog跟zookeeper-3.4.6三个文件夹,data文件夹下建一名为myid的文件,内容分别为1,2,3。

  zookeeper的conf文件夹下有三个配置文件,zoo_sample.cfg为zookeeper的模板配置文件。所需的配置一般可以从该文件中找到。在该文件夹下新建一配置文件叫zoo.cfg,内容为:

  tickTime=2000   
  initLimit=5         
  syncLimit=2
  dataDir=/test/zookeepertest/server1/data
  dataLogDir=/test/zookeepertest/server1/dataLog
  clientPort=2181
  server.1=127.0.0.1:2888:3888
  server.2=127.0.0.1:2889:3889
  server.3=127.0.0.1:2890:3890

  注意:datadir、datalogdir跟clientport三项,在三个zookeeper配置文件中不同。

  除了修改 zoo.cfg 配置文件,集群模式下还要配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面就有一个数据,就是 server.1中的1(server.2就是2,,,),Zookeeper 启动时会读取这个文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是那个 server。

  dataDir跟dataLogDir的路径配置要正确,否则会启动失败,控制台或日志会打印该属性错误,找不到路径。windows下注意路径要双斜线。

  参数说明:
      tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
      dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
      dataLogDir:顾名思义就是 Zookeeper 保存日志文件的目录
      clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
    initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 10 个心跳的时间(也就是 tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 5*2000=10 秒
      syncLimit:这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 2*2000=4 秒
  启动跟简单查看:

  切换到bin目录下,命令行执行./zkServer.sh start 启动zookeeper。启动第一个会报错,因为其它的都没有启动,检测不到其他zookeeper所致,启动第二个zookeeper后第一个报错会停止。
  zookeeper启动后,可以通过telnet来检测是否启动成功:

  

  显示connected to xxxxx. 则表示成功连接到zookeeper,也意味着zookeeper启动成功。
  通过stat命令可以查看当前连接的zookeeper的状态:

  

  mode:follower,我们可以知道当前连接的zookeeper为follower,也就是从机,如果是主机,mode的值应该是leader。

  成功启动后,我们可以通过zookeeper自带的客户端进行一些简单的操作:
  通过运行zkCli.sh可以打开自带客户端,随便输入,按回车,可以看到zookeeper支持的命令列表:
  

  此时,可以通过ls /路径 查看路径目录下的节点内容,根目录为/
  例如,我们可以通过ls / 查看根目录下节点内容,通过create /mynode  myvalue 在根目录下创建mynode节点,节点的值为myvalue,查看某节点用get /路径
  

三、java api 使用

  1、java与zookeeper建立连接:连接的建立过程是异步的,所以如果我们需要在连接建立后进行一些操作,则需要一个“返回函数”,该过程是由watcher类提供的process方法实现。代码如下:

 1 public class CreateSession implements Watcher {
 2     private static ZooKeeper zookeeper;
 3     
 4     public static void main(String[] args) throws IOException, InterruptedException {
 5         zookeeper = new ZooKeeper("127.0.0.1:2181",5000,new CreateSession());
 6         System.out.println(zookeeper.getState());
 7         Thread.sleep(Integer.MAX_VALUE);
 8     }
 9     
10     private void doSomething(){
11         System.out.println("do something");
12     }
13     
14     public void process(WatchedEvent event) {
15         System.out.println("收到事件:"+event);
16         if(event.getState() == KeeperState.SyncConnected){
17             doSomething();
18         }
19     }
20     
21 }

  通过代码测试,发现第7行在注释的情况下,只能输出connecting,

  在不注释的情况下,输出
  CONNECTING
  收到事件:WatchedEvent state:SyncConnected type:None path:null
  do something
  反过来可以发现java通过new zookeeper建立的连接为异步的,代码会在连接没完成的情况下执行完毕,然后退出main方法,导致建立连接后的监听没有执行。

  2、同步方式创建节点

  直接创建节点,create方法的参数分别是:(节点路径,节点值(byte数组),节点权限设置,节点类型(临时节点,持久节点))

 1 public class CreateNodeSync implements Watcher {
 2     private static ZooKeeper zookeeper;
 3     
 4     public static void main(String[] args) throws IOException, InterruptedException {
 5         zookeeper = new ZooKeeper("127.0.0.1:2181",5000,new CreateNodeSync());
 6         System.out.println(zookeeper.getState());
 7         Thread.sleep(Integer.MAX_VALUE);
 8     }
 9     
10     private void doSomething(){
11         try {
12             String path = zookeeper.create("/node_42", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
13             System.out.println("return path:" + path);
14         } catch (KeeperException e) {
15             // TODO Auto-generated catch block
16             e.printStackTrace();
17         } catch (InterruptedException e) {
18             // TODO Auto-generated catch block
19             e.printStackTrace();
20         }
21         System.out.println("do something");
22     }
23     
24     public void process(WatchedEvent event) {
25         System.out.println("收到事件:"+event);
26         if(event.getState() == KeeperState.SyncConnected){
27             doSomething();
28         }
29     }
30     
31 }

  3、异步方式创建节点

   异步方式创建时,create方法需要额外两个参数,一个是一个StringCallback类(回调函数使用),一个是创建该节点时的上下文(当前上下文中需要回调函数中处理的一些内容)

  需要注意的是,如果该节点已经存在,会创建失败,回调函数中rc的值会是-110。创建完成后,可以登录zkCli.sh查看节点内容进行校验,或者程序获取节点内容进行校验。

 1 public class CreateNodeASync implements Watcher {
 2     private static ZooKeeper zookeeper;
 3     
 4     public static void main(String[] args) throws IOException, InterruptedException {
 5         zookeeper = new ZooKeeper("127.0.0.1:2181",5000,new CreateNodeASync());
 6         System.out.println(zookeeper.getState());
 7         Thread.sleep(Integer.MAX_VALUE);
 8     }
 9     
10     private void doSomething(){
11         zookeeper.create("/node_55", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT,new IStringCallback(),"创建");
12     }
13     
14     public void process(WatchedEvent event) {
15         System.out.println("收到事件:"+event);
16         if(event.getState() == KeeperState.SyncConnected){
17             doSomething();
18         }
19     }
20     
21     static class IStringCallback implements AsyncCallback.StringCallback{
22 
23         public void processResult(int rc, String path, Object ctx, String name) {
24             StringBuilder sb = new StringBuilder();
25             sb.append("rc="+rc).append("\n");
26             sb.append("path="+path).append("\n");
27             sb.append("ctx="+ctx).append("\n");
28             sb.append("name="+name);
29             System.out.println(sb.toString());
30         }
31         
32     }
33     
34 }

  zookeeper的java api内容较多,不一一列举。修改、删除节点等操作均有同步跟异步两种方式,两者的主要区别就是异步方式多了一个回调函数,用于处理之后的业务操作。

  使用场景部分,单独在下一篇进行记录。

 

posted @ 2016-05-13 10:46  facelessvoidwang  阅读(990)  评论(0编辑  收藏  举报