大数据培训之Zookeeper零基础-1

Zookeeper

概述

  1. Zookeeper本身是Apache提供的一套开源的用于进行分布式管理和协调的机制/框架。官网:https://zookeeper.apache.org
  2. Zookeeper本身提供了中心化服务 ,包含统一配置、统一命名、分布式锁服务、分布式组服务,更多的时候,Zookeeper充当了一个注册中心来使用
  3. Zookeeper是Yahoo!仿照了Google的<The Chubby Lock Service>开发的后来贡献给了Apache的一套框架

安装

概述

  1. 在大数据中,几乎所有的框架,它的安装都提供了三种模式
    1. 单机模式:在一台服务器上安装,往往能够启动这个框架的部分服务
    2. 伪分布式:在一台服务器上安装,但是利用多个线程模式分布式环境,能够启动这个框架的大部分甚至于服务
    3. 分布式:在集群上安装,能够启动这个框架的所有服务
  2. 现阶段,先安装单机模式,搞定所有的概念之后,再到集群中安装

安装JDK

  1. Centos7.9中可能自带了OpenJDK,需要卸载移除掉

    sh 复制代码
    rpm -qa | grep -i jdk | xargs rpm -ev --nodeps
  2. 上课的时候要求,所有的软件安装包放在/opt/presoftware下,将软件安装在/opt/software

    sh 复制代码
    cd /opt
    mkdir presoftware
    mkdir software
  3. 进入presoftware下,将JDK安装包上传到这个目录下

    sh 复制代码
    cd presoftware
    # 将安装包上传到这个路径下
    rz
  4. 解压到software目录下

    sh 复制代码
    tar -xvf jdk-8u371-linux-x64.tar.gz -C /opt/software/
  5. 进入software目录下

    sh 复制代码
    cd /opt/software/
    # 重命名
    mv jdk1.8.0_371/ jdk1.8
  6. 在Linux中, 环境变量的配置有两个位置:/etc/profile~/.bashrc。无论哪一个路径,默认都会扫描/etc/profile.d目录下的脚本文件,所以,配置环境变量一般是放在/etc/profile.d

    sh 复制代码
    # 需要在/etc/profile.d来脚本文件
    touch /etc/profile.d/javahome.sh
    # 编辑脚本文件
    vim /etc/profile.d/javahome.sh
    # 在文件中添加
    export JAVA_HOME=/opt/software/jdk1.8
    export PATH=$PATH:$JAVA_HOME/bin
    # 保存退出,生效
    source /etc/profile.d/javahome.sh
    # 测试
    javac -version
    # 或者
    java -version

安装Zookeeper(单机模式)

  1. 将安装包上传到Linux上

    sh 复制代码
    cd /opt/presoftware/
    rz
  2. 解压

    sh 复制代码
    tar -xvf apache-zookeeper-3.9.1-bin.tar.gz -C /opt/software/
  3. 重命名

    sh 复制代码
    cd /opt/software/
    mv apache-zookeeper-3.9.1-bin/ zookeeper-3.9.1
  4. 配置环境变量

    sh 复制代码
    # 编辑文件
    vim /etc/profile.d/zookeeperhome.sh
    # 在文件中添加
    export ZOOKEEPER_HOME=/opt/software/zookeeper-3.9.1
    export PATH=$PATH:$ZOOKEEPER_HOME/bin
    # 保存退出,生效
    source /etc/profile.d/zookeeperhome.sh
  5. 配置Zookeeper

    1. 进入Zookeeper的配置目录

      sh 复制代码
      cd /opt/software/zookeeper-3.9.1/conf
    2. 修改配置

      sh 复制代码
      # 复制文件 - 注意:Zookeeper启动的时候默认会使用zoo.cfg中的配置
      cp zoo_sample.cfg zoo.cfg
      # 编辑文件
      vim zoo.cfg
      # 修改dataDir属性的值
      dataDir=/opt/software/zookeeper-3.9.1/data
    3. 启动Zookeeper

      sh 复制代码
      zkServer.sh start
    4. 检查Zookeeper的状态

      sh 复制代码
      # 方式一:
      jps
      # 如果有QuorumPeerMain,那么表示Zookeeper在运行
      # 方式二:
      zkServer.sh status
    5. 进入Zookeeper的客户端

      sh 复制代码
      zkCli.sh

技术点

特点

  1. Zookeeper默认对外提供的客户端端口号是2181,可以通过zoo.cfg中的clientPort属性来修改,但是不建议
  2. Zookeeper本身是一个树状结构,根节点是/
  3. 不同于Linux的地方在于,Zookeeper中没有相对路径的说法,所有节点路径都必须从根节点开始计算
  4. 当Zookeeper启动的时候,自动的添加一个节点/zookeeper,存放的是Zookeeper本身的集群信息
  5. 在Zookeeper3.7及以前的版本中,要求每一个节点在创建的时候必须携带数据,这个数据可以是对节点的描述或者是配置信息
  6. 每一个节点携带的数据默认是在内存以及磁盘上
    1. 维系在内存的目的是为了读写快
    2. 维系在磁盘的目的是为了持久化
  7. 数据在磁盘上的存储路径默认由dataLogDir属性来控制,默认情况下,如果没有单独指定,dataLogDir的属性值和dataDir是一致的
  8. 临时节点下不能挂载子节点!
  9. Zookeeper会为每一次的写操作分配一个全局递增的编号,这个编号称之为事务id,简写为Zxid。一个节点刚被创建的时候,三个事务id是一致的

操作命令

命令 解释
ls / 查看跟节点的子节点
create /big 在根节点下创建子节点big - 这种创建方式是从Zookeeper的3.8版本开始的
create /test 'this is a test server' 在根节点下创建test节点,并且携带数据
create /data '' 创建节点,并且给定数据为空
get /big 获取节点的数据
set /video 'size=500M' 修改数据
delete /test 删除节点,要求节点为空(不能有子节点)
rmr /video 删除这个节点及子节点,从Zookeeper3.8开始,这个命令就过时
deleteall /video 删除这个节点及子节点,从Zookeeper3.8开始建议使用的命令
ls -w / 监控指定节点的子节点的个数变化 - 只监控一次
get -w /news 监控指定节点的数据是否变化 - 只监控一次
removewatches /news 移除监控
history 查看执行过的指令
redo 24 重新执行编号为24的命令
close 关闭连接,但是没有退出Zookeeper客户端
quit 直接退出客户端,需要通过zkCli.sh重新进入
connect localhost:2181 连接本机的2181端口
getAllChildrenNumber / 获取根节点以及所有子节点的数量
setquota -n 2 /news /news节点下的子节点个数最好不要超过2个
setquota -b 1024 /news /news节点的数据最好不要超过1024B
listquota /news 获取/news节点上的限制
delquota /news 删除/news节点上的限制
version 查看Zookeeper的版本
whoami 查看当前的用户
sync / 将根目录下的数据同步给其他的follower
getEphemerals / 获取根节点的临时节点
create -e /big '' 创建临时节点
create -s /test/t '' 创建持久顺序节点
create -e -s /test/t '' 创建临时顺序节点
stat /news 查看节点的属性/信息

节点类型

节点 解释
Persistent 持久节点
Ephemeral 临时节点
Persistent_Sequential 持久顺序节点
Ephemeral_Sequential 临时顺序节点

节点信息/属性

属性/信息 解释
cZxid 这个节点创建对应的事务id,整个过程中第几个写操作创建了这个节点
ctime 这个节点创建对应的时间
mZxid 这个节点的数据修改对应的事务id,整个过程中第几个写操作修改了数据
mtime 这个节点的数据修改对应的时间
pZxid 这个节点的子节点个数变化对应的事务id,整个过程中第几个写操作导致这个节点的子节点个数产生了变化
cversion 这个节点的子节点个数变化了几次
dataVersion 这个节点的数据被修改了几次 - 数据版本
aclVersion 这个节点的权限被修改了几次
ephemeralOwner 如果是持久节点,此项值为0x0;如果是临时节点,此项值为当前的会话编号(sessionid)
dataLength 数据的长度(字节个数)
numChildren 子节点个数

API操作:使用java远程连接并操作Zookeeper

java 复制代码
public class Demo1 {


    ZooKeeper zk;


    @Before         //在所有@Test之前执行
    public void connect() throws Exception {


        /*CountDownLatch是一个同步工具类,它可以使一个或多个线程一直等待,直到其他线程的操作执行完为止。
        在这段代码中,CountDownLatch的作用是等待ZooKeeper客户端连接到ZooKeeper服务器,直到连接事件被
        触发并且状态为SyncConnected时,cdl.countDown() 被调用,才会继续往下执行。这可以保证在客户端连
        接成功之前不会执行后续的操作,从而保证客户端在使用前已经处于连接的可用状态,有效避免操作失败的情况发生。
*/
      /*  在这段代码中,主要涉及到两个线程:主线程和ZooKeeper内部使用的事件处理线程。

        主线程负责执行connect()方法。
        当主线程执行到cdl.await()时,会进入阻塞状态,等待CountDownLatch的计数器减为0。
        ZooKeeper客户端会在另一个线程内部处理连接操作,并执行Watcher中的process()方法。
        当ZooKeeper客户端连接成功后,通过调用cdl.countDown()方法将CountDownLatch的计数器减1。
        主线程检测到CountDownLatch的计数器为0后,解除阻塞状态,继续执行后续代码。
        因此,在这段代码中,主线程会在连接成功之前一直阻塞,直到ZooKeeper客户端连接成功并调用cdl.countDown()后,主线程才会继续执行。这样可以保证在确保连接建立之后再执行后续操作,避免因为连接未建立就开始操作而导致错误
        */
        final CountDownLatch cdl = new CountDownLatch(1);
        zk = new ZooKeeper("192.168.200.130:2181",
                40000,
                new Watcher() {
                    public void process(WatchedEvent watchedEvent) {
                        if (watchedEvent.getState() == Event.KeeperState.SyncConnected)
                            System.out.println("success");
                        cdl.countDown();
                    }
                });

        cdl.await();
    }


    @Test
    public void createNode() throws Exception {

        //参数: 节点路径   数据   权限  类型
        // 返回值是节点路径()  如果是非顺序节点,这个返回值就是第一个路径参数.如果是顺序节点,那么当重名时,就会给节点路径加上序号来返回
        String path = zk.create("/big", "data Server".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
                CreateMode.PERSISTENT);
    }

    @Test
    public void get() throws KeeperException, InterruptedException {
        //节点信息对象
        Stat stat = new Stat();
        //参数: 路径  监控   信息
        byte[] data = zk.getData("/big", null, stat);
        System.out.println(new String(data));
        //这里的时间信息是Long 时间戳
        System.out.println(stat);
    }


    @Test
    public void modify() throws KeeperException, InterruptedException {

        //这个版本必须和dataversion一致
        //KeeperException$BadVersionException: KeeperErrorCode = BadVersion for /java_api
        //防止产生ABA问题(理解ABA问题),确保修改的是最新的数据
        //忽略掉版本校验     -1
        Stat stat = zk.setData("/java_api", "data modify".getBytes(), 0);
        System.out.println(stat);
    }

    @Test
    public void delete() throws KeeperException, InterruptedException {
        //忽略掉版本校验     -1
        zk.delete("/big", -1);
    }

    @Test
    public void getChidren() throws KeeperException, InterruptedException {

        //没用到watcher ,给null
        List<String> children = zk.getChildren("/", null);
        for (String child : children) {
            System.out.println(child);
        }
    }

    @Test
    public void exist() throws KeeperException, InterruptedException {
        //忽略掉版本校验     -1
        Stat stat = zk.exists("/java_api", null);
        System.out.println(stat != null);
    }

    //监控节点是否发生改变
    @Test
    public void nodeDataChange() throws Exception {
        CountDownLatch cdl = new CountDownLatch(1);
     /*   zk.getData("/test",event ->{
            if(event.getType() == Watcher.Event.EventType.NodeDataChanged)
        })*/

  /*      zk.getData("/test", event ->{
            if(event.getType() == Watcher.Event.EventType.NodeDataChanged)
                System.out.println("节点数据被修改");
                cdl.countDown();
        }, null);*/

        zk.getData("/test", event -> {
            if (event.getType() == Watcher.Event.EventType.NodeDataChanged)
                System.out.println("节点数据被修改");
            cdl.countDown();
        }, null);
        cdl.await();
    }

    @Test
    public void nodeChildrenChange() throws Exception {

        CountDownLatch cdl = new CountDownLatch(1);

        zk.getChildren("/test", event -> {
            if (event.getType() == Watcher.Event.EventType.NodeDataChanged)
                System.out.println("节点数据被修改");
            cdl.countDown();
        });


//        zk.getChildren("/test", new Watcher() {
//            @Override
//            public void process(WatchedEvent watchedEvent) {
//
//            }
//        })
    }

    @Test
    public void nodeChange() throws Exception {
        CountDownLatch cdl = new CountDownLatch(1);
        zk.exists("/big", event -> {
            if (event.getType() == Watcher.Event.EventType.NodeCreated)
                System.out.println("节点被创建");
            else if (event.getType() == Watcher.Event.EventType.NodeDeleted)
                System.out.println("节点被删除");
            cdl.countDown();
        });
        cdl.await();
    }
}
相关推荐
艾莉丝努力练剑18 分钟前
【Git:综合复盘】Git 原理与使用
大数据·人工智能·git·elasticsearch·面试
IT研究室24 分钟前
最新大数据毕业设计选题推荐-基于大数据的全球地震活动时空分布分析与可视化-大数据-Spark-Hadoop-Bigdata
大数据·信息可视化·数据分析·spark·课程设计
计算机源码社31 分钟前
基于Hadoop+Spark的商家优惠券营销效果数据分析与可视化-基于Python的商家优惠券营销效果检测与评估分析系统
大数据·hadoop·python·数据挖掘·spark·毕业设计·数据可视化
AcaDesign36 分钟前
上海市科技奖申报答辩ppt制作案例_科技进步奖ppt模板_技术发明奖ppt设计_自然科学奖ppt美化
大数据·科技·powerpoint
Raas1007 小时前
MAI Gateway(魔芋企业级AI网关)技术揭秘:AI网关支持哪些模型?从原理到落地
大数据·人工智能·网关·gateway·mai gateway·企业级产品
YangYang9YangYan10 小时前
2026 校招商品分析岗位 JD 拆解,核心指标、工具与面试考点
大数据·数据库·数据分析
大大大大晴天10 小时前
OpenMetadata VS DataHub VS Atlas VS Gravitino
大数据
Qyr9913 小时前
2026全球汽车碳刷行业发展全景分析报告
大数据
蓝速科技14 小时前
便民服务大厅 AI 数字人一体机场景适配与落地指南丨蓝速科技
大数据·网络·数据结构·人工智能·自然语言处理·数据分析·运维开发
精益数智工坊14 小时前
云计算环境数据怎么同步?云计算集成方案有哪些?
大数据·人工智能·数据挖掘·数据可视化