Zookeeper工作原理概述和监听机制概览

1. Zookeeer是什么?

专业解释:分布式协调服务组件

通俗的解释:劝架者,仲裁机构

作用:如果有多个角色出现了分歧,没法达成一致,ZooKeeper 帮我们达成一致

What is ZooKeeper?

Apache ZooKeeper is an effort to develop and maintain an open-source server which

enables highly reliable distributed coordination

ZooKeeper is a centralized service for maintaining configuration information, naming,

providing distributed synchronization, and providing group services. All of these kinds

of services are used in some form or another by distributed applications. Each time they are

implemented there is a lot of work that goes into fixing the bugs and race conditions that

are inevitable. Because of the difficulty of implementing these kinds of services,

applications initially usually skimp on them ,which make them brittle in the presence ofchange and difficult to manage. Even when done correctly, different implementations of

these services lead to management complexity when the applications are deployed

ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的

实现。它提供了简单原始的功能,分布式应用可以基于它实现更高级的服务,比如分布式同步,配置管

理,集群管理,命名管理,队列管理。它被设计为易于编程,使用文件系统目录树作为数据模型。服务

端跑在 Java 上,提供 Java 和 C 的客户端 API。

官网地址:http://ZooKeeper.apache.org/

官网快速开始地址:http://zookeeper.apache.org/doc/current/zookeeperStarted.html

官网API地址:http://ZooKeeper.apache.org/doc/r3.4.10/api/index.html

ZooKeeper在分布式领域,能够帮助解决很多很多的分布式难题,但是底层却只是依赖于两个主要的组件:

1、ZNODE文件 也就是数据存储系统,为分布式应用存储少量的关键的核心状态数据

2、WATCH监听,如果客户端对这个znode中的某个数据感兴趣,zookeeper可以提供一个监听服务,客户端去注册这个数据的监听,如果这个数据发生了变化,那么我们的zookeeper就会把监听的信息发送给客户端

2. Zookeeper的Znode存储系统

其实就是文件系统(树形结构,每个节点可以是目录也可以是文件夹)

没有文件夹和文件的区别,就叫做znode,这个znode既可以挂载子节点,也能存储数据

ZK的命名空间就是zk应用的文件系统,他和Linux的文件系统很像,也和我们看过的HDFS源码的目录树INODE很像,也是树形的,这样就可以确定每个路径都是唯一的,对于命名空间的操作必须都是绝对路径操作,与Linux文件系统不同的是,Linux文件系统有目录和文件的区别,而Zookeeper统一叫做Znode,一个znode节点下面可以包含子znode,同时该及诶到哪也可以存储数据。

所以总结来说,znode即是文件夹又是文件的概念,但是在zk这里面就不叫文件也不叫文件夹叫znode,每个znode有唯一的路径标识,既可以存储数据,也能创建znode,但是znode只适合存储非常少量的数据,不能超过1M,最好小于1K

image-20200808155403459

ZNODE一般情况下,可以分为两类:

  • 按照声明周期
    • 短暂(ephemeral)断开连接自己删除
      • 带有序列编号(SEQUENTIAL)
      • 和不带有序列编号
    • 持久(persistent)断开连接不删除
      • 带有序列编号(SEQUENTIAL)
      • 和不带有序列编号

详细解释

节点类型详解
PERSISTENT持久化 znode 节点,一旦创建这个 znode 节点,存储的数据不会主动消失,除非是客户端主动 delete
PERSIENT_SEQUENTIAL自动增加自增顺序编号的 持久化znode 节点,编号递增,而且是唯一的
EPHEMERAL临时znode节点,断开连接后失效
EPHEMERAL_SEQUENTIAL临时自增顺序编号的持久化znode节点,编号递增,而且是唯一的

注意点:

  • 创建znode时设置顺序标识,znode名称后会附加一个值,顺序编号是一个单调递增的计数器,由父节点维护
  • 在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断时间的顺序
  • EPHEMERAL类型的节点不能有子节点,所以只能是叶子节点
  • 客户端可以在znode上设置监听器

3. Zookeeper的监听机制

3.1 概述

客户端注册它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目录节点增加删除)时,zk会通知客户端,监听机制保证zk保存的任何的数据的任何改变都能快速的响应到监听了该节点的应用程序

监听器的工作机制,其实是在客户端会专门创建一个监听线程,在本机的一个端口上等待zk集群发送过来的事件

image-20200808162350708

image-20200808162256316

注意:注册的监听事件在事件响应之后就失效了

监听工作原理:

Zookeeper的Watcher机制主要包括客户端线程、服务端WatcherManager、Zookeeper服务器三部分,客户端在向Zookeeper服务器注册的同时,会将Watcher对象存储在客户端的WatcherManager当中,当Zookeeper服务器触发Watcher事件后,会向客户端发送通知(WatchedEvent),客户端线程从WatcherManager中取出对应的Watcher对象来执行回调逻辑。

image-20200808162950349

工作流程

  1. 如果某个客户端A对zookeeper系统中的某个节点/a1/b1的数据变化感兴趣,需要注册一个监听,zookeeper.getData(watch)
  2. 客户端会生成一个WatchManager服务,专门用来管理各种Watch对象
  3. 等待响应
  4. 如果zookeeper系统真的检测到你感兴趣的znode节点发生变化,那么zk就会返回一个消息:WatchedEvent,包含三个信息,Path、EventType、connect状态
  5. 客户端就会根据这个watchedevent的信息,来决定回调那个watch对象中的process方法
  6. 在进行开发的时候,都会提前把对应的业务逻辑都编写在process方法中

3.2 总结

zookeeper只为我们提供了两个功能

1、Znode系统,存储一些关键数据,类似于unix文件系统
2、watch监听机制,可以让客户端有能力实时感知zookeeper代为保管的数据的变化,从而进行相应处理。

4. Zookeper监听机制的简单使用

package de;

import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * Copyright (c) 2019 bigdata ALL Rights Reserved
 * Project: learning
 * Package: de
 * Version: 1.0
 *
 * @author qingzhi.wu 2020/8/8 11:11
 */
public class ZookeeperTest2 {
    private final static String zkConnectionIps = "hadoop01:2181,hadoop02:2181,hadoop03:2181";
    // 1
    private final static String path = "/de_a";
    private  static ZooKeeper zk = null;

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        //TODO 1.获取连接

        zk =  new ZooKeeper(zkConnectionIps, 4000, new MyWatch());

        if (zk.exists(path,null) == null){
            zk.create(path, "wuwu".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }


        //让线程不退出
        TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);

        //TODO 5.关闭连接
        zk.close();

    }

    static class MyWatch implements Watcher {

        @Override
        public void process(WatchedEvent event) {

            //连接状态信息
            Event.KeeperState state = event.getState();
            //事件类型
            Event.EventType type = event.getType();
            //路径
            String nodePath = event.getPath();

            System.out.println("state: " + state + "\t" + "type: " + type + "\t" + "path: " + path);
            // 4
            if (state == Event.KeeperState.SyncConnected && type.equals(Event.EventType.None) && nodePath == null) {
                System.out.println("初始化连接。。。");
            } else if(path.equals(nodePath) && type == Event.EventType.NodeDataChanged){
                System.out.println("节点数据值被改变");
            } else if(path.equals(nodePath) && type == Event.EventType.NodeDeleted){
                System.out.println("节点被删除");
            }

            try {
                zk.getData(path, true, null);
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值