Zookeeper

Posted zqq_hello_world

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zookeeper相关的知识,希望对你有一定的参考价值。

Zookeeper

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等

ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户

  • Zookeeper本质上是一个分布式小文件存储系统。提供基于类似文件系统的目录树方式的数据存储,并且可以对树中的结点进行有效管理。
  • Zookeeper提供给客户端监控存储在Zookeeper内部数据的功能,从而可以达到基于数据的集群管理。如:同一命名服务(dubbo)、分布式配置管理、分布式消息队列、分布式锁、分布式协调等。

架构组成

Leader

  • 集群内各个服务器的调度者

  • Zookerper集群工作核心角色,事务(增删改)请求的唯一处理者,Follower节点会把事务请求转发给Leader处理,如上图。Leader不是用户手动指定,是选举出来的。

Follower

  • 参与Leader的选举

  • 处理读请求转发事务请求给Leader

Observer

  • 观察者角色,观察Zookeeper集群的最新状态变化并将这些状态同步过来,对于非事务请求可以进行单独处理,对于事务请求则会转发给Leader服务器进行处理
  • 不会参与任何形式的投票只提供非事务服务。通常用于在不影响集群事务处理能力的前提下提升集群非事务处理能力。增加了集群的并发的读请求

数据结构

Zookeeper中,数据信息被保存到一个个数据节点上,这些节点被称为ZNode。ZNode是Zookeeper中最小数据单位,ZNode下面又可以挂ZNode(类似Linux的文件目录结构),一层层的ZNode形成了一个层次化的ZNode树,数据以key-value形式存储,如图

ZNode节点类型

Zookeeper节点类型可以分为三大类

  • 持久性节点(Persistent)
  • 临时性节点(Ephemeral)
  • 顺序性节点(Sequential)

在开发中创建节点通过组合可以生成四种类型节点:持久节点、临时节点、持久顺序节点、临时顺序节点

  • 持久节点:是Zookeeper最常见的一种节点类型,持久节点被创建后会一直存在服务器,直到删除操作主动清除
  • 临时节点:会被自动清理掉的结点,它的声明周期和客户端会话绑在一期,客户端会话结束,节点会被删除,与持久节点不同的是,临时节点不能创建子节点
  • 持久顺序节点:就是有顺序的持久节点,节点特性和持久节点一样。顺序特性实质是在创建节点的时候,会在节点名后面加上一个数组后缀来表示顺序。
  • 临时顺序节点:就是有顺序的临时节点,和持久顺序节点的顺序性相同。

Watcher机制

Zookeeper使用Watcher机制实现分布式数据的发布/订阅功能。在Zookeeper中,引入了Watcher机制来实现分布式通知功能,Zookeeper允许客户端向服务端注册一个Watcher监听,当服务端的一些指定事件触发了这个Watcher,那么Zookeeper就会向指定客户端发送一个事件通知来实现分布式通知功能。

Zookeeper的Watcher机制主要包括客户端线程、客户端WatcherManager、Zookeeper服务器三部分。工程流程为:

  • 客户端向Zookeeper服务器注册的同时,会将Watcher对象存储在客户端的WatcherManager当中
  • 当Zookeeper服务器触发Watcher事件后,会向客户端发送通知
  • 客户端线程从WatcherManager中取出对应的Watcher对象来执行回调逻辑

常用命令

连接客户端

#连接本地
./zkCli.sh
#连接远程
./zkCli.sh -server 192.168.65.135:2181

查看所有节点

 # ls /[节点名称]
 ls /

创建节点设置节点数据

# create /[节点名称] [节点数据]
create /znode
#创建临时节点,会话关闭临时节点清除
create -e /znode1

删除节点

 #delete /[节点名称]
 delete /znode

设置节点数据

 # set /[节点名称] [数据]
 set /znode 'this is data'

获取节点数据

# get /[节点名称] ,
get /znode
#获取节点所有信息(数据+信息)
get -s /znode

zkclient简单使用

引入maven依赖

   <!--Zookeeper-->
   <dependency>
       <groupId>org.apache.zookeeper</groupId>
       <artifactId>zookeeper</artifactId>
       <version>3.6.2</version>
   </dependency>

   <!-- zkclient -->
   <dependency>
       <groupId>com.101tec</groupId>
       <artifactId>zkclient</artifactId>
       <version>0.10</version>
       </dependency>
   </dependencies>

获取zkClinet客户端连接

private static ZkClient zkClient = null;

static 
    //0.获取ZkClient对象。连接zookeeper
    zkClient = new ZkClient("192.168.136.133:2181");

创建删除节点

/**
 * 创建删除节点
 */
private static void demo1() 
    //0.获取ZkClient对象。连接zookeeper
    System.out.println("=====ZkClient Connection successful=======");
    //1.创建节点,第一个参数节点信息,第二个参数true代表父节点不存在创建父节点
    zkClient.createPersistent("/zqq/data-node",true);
    //zkClient.writeData("","this is data");
    //2.删除节点,delete不支持递归删除
    //zkClient.delete("/zqq/data-note");
    //2.递归删除节点
    zkClient.deleteRecursive("/zqq");
    zkClient.close();

监听器监听节点变化

/**
 * zkClient使用监听器
 */
private static void demo2() throws Exception

    //zkClient对指定目录进行监听,指定收到通知之后的逻辑。一直监听
    zkClient.subscribeChildChanges("/zqq", new IZkChildListener() 
        /**
         * 监听方法
         * @param s 监听的节点
         * @param list 监听节点下的子节点
         * @throws Exception
         */
        public void handleChildChange(String s, List<String> list) throws Exception 
            //自定义处理逻辑
            System.out.println(Thread.currentThread().getName() + "===:" + "监听:" + s + ";子结点:" + list);
        
    );

    //使用zkClient创建、删除节点,验证监听器是否生效
    zkClient.createPersistent("/zqq");
    Thread.sleep(2 * 1000);
    zkClient.createPersistent("/zqq/data-node");
    Thread.sleep(2 * 1000);
    zkClient.delete("/zqq/data-node");
    Thread.sleep(2 * 1000);
    zkClient.delete("/zqq");
    zkClient.close();

监听器监听节点数据变化

/**
 * 使用监听器监听节点数据的变化
 */
private static void demo3() throws Exception
    //1.判断节点是否存在,不存在创建节点
    if(!zkClient.exists("/zqq"))
        zkClient.createPersistent("/zqq");
    

    //2.注册监听器,监听节点数据的改变
    zkClient.subscribeDataChanges("/zqq", new IZkDataListener() 

        /**
         * 数据改变触发方法
         * @param s 节点
         * @param o 数据
         * @throws Exception
         */
        public void handleDataChange(String s, Object o) throws Exception 
            //自定义处理逻辑
            System.out.println(Thread.currentThread().getName() + "===:" + s + ";data change;==" + o);
        

        /**
         * 数据删除触发方法
         * @param s 节点
         * @throws Exception
         */
        public void handleDataDeleted(String s) throws Exception 
            //自定义处理逻辑
            System.out.println(Thread.currentThread().getName() + "===:" + s + " is deleted");
        
    );

    //3.读取数据 写入数据 删除数据
    Object o = zkClient.readData("/zqq");
    System.out.println("读取到数据:" + o);
    Thread.sleep(2 * 1000);
    //写入新数据
    zkClient.writeData("/zqq","new data");
    Thread.sleep(2 * 1000);
    //删除节点
    zkClient.delete("/zqq");
    Thread.sleep(2 * 1000);
    zkClient.close();

参考教程

菜鸟教程—Zookeeper

以上是关于Zookeeper的主要内容,如果未能解决你的问题,请参考以下文章

引用的实质

Spring 框架学习——IOC思想原型及实质

必须掌握!你知道 Spring 中运用的 9 种设计模式吗?

为什么说逻辑回归实质是最大似然估计,而线性回归实质是最小二乘法?

Generator实质

数据智能时代:数据体系建设的实质、思路和方式