大数据系列之协同服务Zookeeper知识整理(二)Zookeeper上的数据操作,使用JAVA API来访问Zookeeper

1.Zookeeper上的数据操作

上一篇中我们介绍了zk是什么,以及zk的工作流程。既然zk是协调服务的,那必然会存储一些节点的信息,比附说Hadoop高可用集群HA的活跃NameNode信息,活跃ResourceManager信息(后面会介绍配置HA),Kafka的消息对了等等一些分布式节点信息,那这些基本信息是存储在zk哪里的,以及格式是什么样子?

启动zk的客户端与服务器

  $>bin/zkServer.sh start

   $>zkCli.sh -server s10:2181    //进入zk命令行

我们在客户端使用help来查看一下帮助,看看zk有哪些命令

  $zk]help                        //查看帮助

我们看到有一个create命令,这个就是用来创建数据的,根据提供的格式,我们可以看到格式是create path  data,说明了zk在创建数据的时候是创建了一个目录,目录上有数据啊,这点特别重要,这就是zk上的数据格式。zk上存放的数据格式是:目录   数据。也就是创建的每一个目录都有值,我们试着创建一下:

我们看到最后一个创建的目录是 /a/a1,但在创建之前目录/a必须存在,只能先创建父节点,再创建子节点,并且每次在创建的时候必须给予值,否则不会创建成功。创建完成之后我们ls /查看一下

不给值,创建不成功

看到都是一层层的目录

使用 get 目录 来获得这个目录的值

注意:在get命令获得这个目录的数据之后,我们会发现有一个特别重要的属性:dataVersion:数据的版本(自增,没修改一次加1)。zk使用这个属性来控制并发,在进行修改数据的时候,只有修改数据操作的版本号与其一致,zk才允许其进行修改,例如同时有两个线程A,B同时修改目录/a的数据,版本号就会对其进行控制,假设A先修改数据,数据版本经查看后一致,允许修改,并且同时版本号加1,B再修改的时候就会发现版本号不一致(因为A,B在同一版本号操作,A的操作导致版本号加1),则不会允许进行操作。

使用 set 目录  数据 修改这个目录的值

我们看到create命令,后面有两个可选择的命令,分别是[s],[e]分别代表什么意思呢,[s]-序列目录,[e]-临时目录

zk中的3种目录类型
-----------------
    1.持久目录(默认,不加[e],[s])
        client结束,还存在。
        
    2.临时目录
        在client活动时有效,断开自动删除。临时目录不能有子目录。
        leader推选是使用。

    3.序列目录
        在目录名之后附加10个数字,主要用于同步和锁.

那zk上的数据都保存在哪里了呢?在我们上一篇搭建单机版zk的zoo.cfg目录中配置的

version-2文件夹里面有数据文件,只不过对数据进行了一些操作(比如加密,编译等类似操作)。

这个目录就是zk用来存储协同分布式服务时的一些数据,并且数据格式是目录。

2.使用JAVA API来访问Zookeeper

(pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.it18zhang</groupId>
    <artifactId>ZooKeeperDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.9</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
    </dependencies>
</project>

(java文件)

package com.hadoop.zktest;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.junit.Test;

import java.util.List;

/**
 *
 */
public class TestZK { 

   //显示所有根目录

    @Test
    public void ls() throws  Exception{
        ZooKeeper zk = new ZooKeeper("s10:2181",5000,null);
        List<String> list = zk.getChildren("/",null);
        for(String s : list){
            System.out.println(s);
        }
    }

   //显示所有目录

    @Test
    public void lsAll() throws  Exception{
        ls("/");
    }

    /**
     * 列出指定path下的孩子
     */
    public void ls(String path) throws  Exception{
        System.out.println(path);
        ZooKeeper zk = new ZooKeeper("s10:2181",5000,null);
        List<String> list = zk.getChildren(path,null);
        if(list == null || list.isEmpty()){
            return ;
        }
        for(String s : list){
            //先输出孩子
            if(path.equals("/")){
                ls(path + s);
            }
            else{
                ls(path + "/" + s);
            }
        }
    }

    /**
     * 设置数据
     */
    @Test
    public void setData() throws Exception{
        ZooKeeper zk = new ZooKeeper("s10:2181", 5000, null);
        zk.setData("/a","tomaslee".getBytes(),0);
    }

    /**
     * 创建临时节点
     */
    @Test
    public void reateEmphoral() throws Exception{
        ZooKeeper zk = new ZooKeeper("s10:2181", 5000, null);
        zk.create( "/c/c1" ,"tom".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);

        System.out.println("hello");
    }

    //观察者模式(zk提供观察者模式来在数据更改时用来感知变化,也供leader的选择)

    //观察。
   // client能够通过watch机制在数据发生变化时收到通知。
   // client可以在read 节点时设置观察者。watch机制会发送通知给注册的客户端。
    //观察模式只触发一次。
   // session过期,watch机制删除了。

    @Test
    public void testWatch() throws Exception{
        final ZooKeeper zk = new ZooKeeper("s10:2181", 5000, null);

        Stat st = new Stat();

        Watcher w = null ;
        w = new Watcher() {
            //回调
            public void process(WatchedEvent event) {
                try {
                    System.out.println("数据改了!!!");
                    zk.getData("/a", this, null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        byte[] data = zk.getData("/a", w , st);

        System.out.println(new String(data));

        while(true){
            Thread.sleep(1000);
        }
    }


}
leader推选过程(最小号选举法)
-------------------
    1.所有节点在同一目录下创建临时序列节点。
    2.节点下会生成/xxx/xx000000001等节点。
    3.序号最小的节点就是leader,其余就是follower.
    4.每个节点观察小于自己节点的主机。(注册观察者)
    5.如果leader挂了,对应znode删除了。
    6.观察者收到通知。
    7.序号最小的节点就是leader

更加具体的博文

https://www.cnblogs.com/felixzh/p/5869212.html

猜你喜欢

转载自blog.csdn.net/u011444062/article/details/81075873