zookeeper从安装到入门

news2025/7/19 10:18:01

文章目录

  • 什么是zookeeper
  • zookeeper的安装
  • 启动zookeeper并检查是否安装完成
  • zookeeper的一些操作指令
  • zookeeper的JavaAPI
    • 建立连接
    • 创建节点
    • 查询节点
    • 修改节点
    • 删除节点
    • 事件监听
  • 分布式锁
  • 集群
    • leader选举规则
    • 集群角色

什么是zookeeper

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Hadoop和Hbase的重要组件。

zookeeper翻译过来就是动物管理员,是管理Hadoop(大象),Hive(蜜蜂),Pig(小猪)的管理员。

zookeeper提供的主要功能包括:配置管理,分布式锁,集群管理

zookeeper的安装

我使用的是centos,于是我直接用wget命令下载下来。其他虚拟机或本地下载也可以到下面的网址下载压缩包

wget http://archive.apache.org/dist/zookeeper/zookeeper-3.5.9/apache-zookeeper-3.5.9-bin.tar.gz

之后将文件解压缩到一个自己常用的放文件的地方

tar -zxvf apache-zookeeper-3.5.9-bin.tar.gz -C /export/server

为了之后打开文件的方便,我们还可以给文件加一个软连接

ln -s /export/server/apache-zookeeper-3.5.9-bin /export/server/zookeeper

进入该目录

cd /export/server/zookeeper/conf

通过mv命令改名

mv zoo_sample.cfg zoo.cfg

你可能会好奇,为什么要改名。
官方文档中提到启动zookeeper需要一个配置文件,而这个配置文件的默认名字就是zoo.cfg,而oo_sample.cfg只是配置文件的一个示例,而我们通过改名直接把这个实例当成配置文件去使用,比较的快捷和方便,只需要修改一下参数,就可以使用了

打开文件

vim /export/server/zookeeper/conf/zoo.cfg

修改一下参数

tickTime=2000
# zookeeper数据存储目录
dataDir=/export/server/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2

要注意这里的dataDir后面的data文件夹是不存在的,需要我们自己手动创建
这个文件夹是用于我们存放数据的

到这里我们的zookeeper就算是安装完毕了

启动zookeeper并检查是否安装完成

我们可以使用一下命令启动zookeeper

/export/server/zookeeper/bin/zkServer.sh start

之后可以查看一下zookeeper服务的状态

/export/server/zookeeper/bin/zkServer.sh status

之后启动zookeeper客户端程序,进入到zookeeper的控制台中

/export/server/zookeeper/zkCli.sh

使用一下命令查看

ls /

在这里插入图片描述
如果你的结果和我一样,那么恭喜你,你的zookeeper已经装好了

zookeeper的一些操作指令

ls          查看该目录下的文件
ls -s       产看该节点的详细信息
creat       创建新文件 注意一定要有父节点才能创建子节点
create -e   创建临时节点,即关闭当前会话该节点会自己消失
create -s   创建顺序节点,会在你创捷的节点名字后面自动添加编号
get         获取节点的数据
set         修改节点的数据
delete      删除节点,但是无法删除有子节点的节点
deleteall   可以删除带有子节点的节点

zookeeper的JavaAPI

我们通过curator来简化原生的API调用

建立连接

/*
        * connectString  连接字符串  地址和端口
        * sessionTimeoutMs    会话超时时间  ms
        * connectionTimeoutMs   连接超时时间  ms
        * retryPolicy    重试策略
        *
        *
        * */


        //重试策略
        RetryPolicy retryPolicy=new ExponentialBackoffRetry(3000,10);

        /*方法一*/
       CuratorFramework client =
                CuratorFrameworkFactory.newClient("192.168.88.130:2181", 60000, 15000, retryPolicy);

        /*方法二
         * */
         client = CuratorFrameworkFactory.builder().connectString("192.168.88.130:2181")
                .sessionTimeoutMs(60000)
                .connectionTimeoutMs(15000)
                .retryPolicy(retryPolicy)
                //名称空间,所有的操作都会在xxx节点下
                 .namespace("xxx")
                .build();

        client.start();

创建节点

@Test
    public void testCreate1() throws Exception {
        //如果创建节点,没有指定数据,默认为将当前的客户端的ip当为数据
        String path=client.create().forPath("/app1");
        System.out.println(path);
    }

    @Test
    public void testCreate2() throws Exception {
        //如果创建节点,没指定数据
        String path=client.create().forPath("/app2","114514".getBytes(StandardCharsets.UTF_8));
        System.out.println(path);
    }


    @Test
    public void testCreate3() throws Exception {
        //设置节点的类型,默认为持久节点
        String path=client.create().withMode(CreateMode.EPHEMERAL).forPath("/app3","114514".getBytes(StandardCharsets.UTF_8));
        System.out.println(path);
    }

我们可以进入CreatMode中看看
在这里插入图片描述
可以发现它是一个枚举类,上面的这些就是我们的节点属性

查询节点

@Test
    public  void testGet1() throws Exception {
        //查询数据
        byte[] data = client.getData().forPath("/app1");
        System.out.println(new String(data));
    }


    @Test
    public  void testGet2() throws Exception {
        //查询子节点
        List<String> path = client.getChildren().forPath("/app4");
        System.out.println(path);
    }


    @Test
    public  void testGet3() throws Exception {
        //查询节点状态信息
        Stat status=new Stat();
        byte[] data = client.getData().storingStatIn(status).forPath("/app1");
        System.out.println(new String(data));
        System.out.println(status);
    }

修改节点

//直接修改
    @Test
    public void testSetData() throws Exception {
        client.setData().forPath("/app1","114514".getBytes(StandardCharsets.UTF_8));
    }

    //根据版本修改

    @Test
    public void testSetDataVersion() throws Exception {

        Stat status=new Stat();
        client.getData().storingStatIn(status).forPath("/app1");
        int version=status.getVersion();
        System.out.println(version);
        client.setData().withVersion(version).forPath("/app1","1919810".getBytes(StandardCharsets.UTF_8));
    }

删除节点

//删除单个节点
    @Test
    public void testDelete() throws Exception {
        client.delete().forPath("/app1");
    }


    //删除带有子节点的节点
    @Test
    public void testDelete2() throws Exception {
        client.delete().deletingChildrenIfNeeded().forPath("/app4");
    }


    //保证删除
    @Test
    public void testDelete3() throws Exception {
        client.delete().guaranteed().forPath("/app2");
    }

    //回调
    @Test
    public void testDelete4() throws Exception {
        client.delete().guaranteed().inBackground(new BackgroundCallback() {
            @Override
            public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
                System.out.println("删除成功");
                System.out.println(curatorEvent);
            }
        }).forPath("/app2");
    }

事件监听

zookeeper通过watcher机制实现实现了发布/订阅功能,能够让多个订阅者监听某一个对象,当一个对象自身发生状态变化是会通知所有的订阅者。
zookeeper提供了三种watcher
nodeCache:只监听某一个特定的节点
PathCildrenCache:监控一个节点所有的子节点,不包括他本身
TreeCache:监控一个树上的所有节点,相当于PathCildrenCache,但是同时监控这个节点本身


@Test
    public void testNodeCache() throws Exception {
        NodeCache nodeCache=new NodeCache(client,"/app1");
        nodeCache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                System.out.println("节点变化");


                byte[] data = nodeCache.getCurrentData().getData();
                System.out.println(new String(data));
            }
        });
        nodeCache.start();

        while (true){

        }
    }



    @Test
    public void testPathchildrenCache() throws Exception {
        PathChildrenCache pathChildrenCache=new PathChildrenCache(client,"/app2",true);


        pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
            @Override
            public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {

                System.out.println("子节点变化");
                PathChildrenCacheEvent.Type type=pathChildrenCacheEvent.getType();
                //监听子节点的更新,并但会更新后的数据

                //设置一个过滤器,只监听update的情况
                if(type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
                    System.out.println("数据发生改变");
                    byte[] data = pathChildrenCacheEvent.getData().getData();
                    System.out.println(new String(data));
                }
            }
        });

        pathChildrenCache.start();

        while (true){

        }
    }


    @Test
    public void testTreeCache() throws Exception {

        TreeCache treeCache=new TreeCache(client,"/app2");



        treeCache.getListenable().addListener(new TreeCacheListener() {
            @Override
            public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
                System.out.println("节点变化了");
                System.out.println(treeCacheEvent);
            }
        });

        treeCache.start();

        while (true){

        }
    }

分布式锁

当我们在进行单机开发是常常采用sysnchronized或lock的方式解决线程同步问题,但是当我们的服务分布在个个服务器中的时候,这种方法已经不再使用了,因而我们引用了分布式锁的概念来解决线程同步问题。

创建的分布式锁有三种实现方式,第一种是以redis为代表的基于缓存实现的分布式锁,第二种就是我们的zookeeper实现的分布式锁,第三种就是基于数据库的悲观锁和乐观锁。

那么,我们的zookeeper又是如何实现分布式锁的呢

zookeeper实现分布式锁的核心就是当用户要获取锁时创建节点,用完时删除该节点
1.当用户获取到锁时,会在lock节点下创建一个临时顺序节点
2.之后获取lock节点下所有的子节点,当该节点的序号最小,我们就默认该节点获取到锁,用完之后将其删除
3.如果当前节点并非最小的节点,则该节点会找到比自己小1的节点,并对其注册事件监听器
4.如果收到该节点删除的消息,则该节点获取到锁

集群

leader选举规则

所有的服务器会推举最新加入集群的服务器作为leader,一个服务器超过了半数的服务器的推举,就会成为leader。当选举出了leader之后,新加入的服务器便不会在进行选举了。

当leader挂掉后,会重新选举出新的leader

集群角色

leader:处理事务请求,集群内部各服务器的调度者
follower:处理客户端非事务请求,转发请求事务给leader;参与leader选举投票
observer:与follower作用相同,但是不参与leader选举

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/395743.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Fastjson 1.2.24 命令执行漏洞复现-JNDI简单实现反弹shell

文章目录前言一、环境搭建二、漏洞复现准备三、漏洞复现四、不成功的原因&#xff08;排查&#xff09;&#xff1a;总结前言 网上文章千篇一律&#xff0c;导致很多人都只会一种方法&#xff0c;只要有一种办法就所有人跟着这个办法去做了&#xff0c;新建java文件&#xff0…

Azure Function App Deploy Issue

问题&#xff1a;之前一直用vs code 的 Azure Function extension 工具部署&#xff0c;没有什么问题。直到3月份发现 vs code显示部署成功&#xff0c;但是通过 https://<function_name>.scm.azurewebsites.net/DebugConsole 查看上传后的 dll 文件&#xff0c;dll文件根…

每日学术速递3.8

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Unleashing Text-to-Image Diffusion Models for Visual Perception 标题&#xff1a;释放用于视觉感知的文本到图像扩散模型 作者&#xff1a;Wenliang Zhao, Yongming Rao, Zuya…

【maven 学习记录】

maven 学习记录一、maven基础1. maven是什么2. maven的作用3. maven的下载安装4. maven仓库5. maven坐标6. 第一个maven项目 手工实现7. maven插件8. 依赖管理9. 生命周期二、maven进阶一、maven基础 1. maven是什么 maven的本质是一个项目管理工具&#xff0c;将项目开发和管…

mac电脑解决Error: command failed: npm install --loglevel error --legacy-peer-deps

使用vue create xxx创建vue3项目的时候报错。 解决步骤&#xff1a; 1.sudo npm cache clean --force 2.再次创建就可以成功 补充&#xff1a;网上搜到很多方法&#xff0c;都尝试失败&#xff0c;因为遇到需要打开.vuerc,.npmrc的情况&#xff0c;记录一下怎样找到文件 1. 尝…

xshell的复制ssh渠道和复制会话是什么意思

xshell的复制ssh渠道和复制会话是什么意思1、复制ssh渠道1.1、只打开一个标签页时1.2、复制ssh渠道后1.3、复制第2个ssh渠道后2、复制会话3、两个ssh进程分别复制ssh渠道4、总结1、复制ssh渠道 1.1、只打开一个标签页时 ssh进程有1个&#xff0c;pid是98959。用户是root、终端…

工业级64 位AM6231ASGGGAALW/AM6232ATCGGAALW【处理器】AM6234ATCGGAALW

工业级64 位AM6231ASGGGAALW/AM6232ATCGGAALW【处理器】AM6234ATCGGAALW说明&#xff1a;低成本的AM62x Sitara MPU系列应用处理器专为Linux 应用开发而设计。凭借可扩展的ArmCortex -A53性能和嵌入式功能&#xff0c;例如:双显示支持和3D图形加速&#xff0c;以及广泛的外围设…

Flutter-自定义图标

虽然Flutter有许多内置的icon图标&#xff0c;但是有些特殊功能的话&#xff0c;需要自定义图标或者需要在iconfont 阿里巴巴的图标库里找对应合适的图标。 第一步&#xff1a;在iconfont 阿里巴巴里搜索想要的图标并加入到购物车&#xff0c;点击下载代码后&#xff0c;会生成…

2023增加收入的最佳销售聊天机器人

哈佛大学的研究表明&#xff0c;快乐的客户花费更多。聊天机器人可以很大程度提高客人体验感&#xff0c;可以增加您的销售额。现在&#xff0c;快来get市场上最好的销售聊天机器人并增加您的收入&#xff01; 一、什么是销售聊天机器人&#xff1f; 销售聊天机器人是一种自动…

使用 Wall 教你搭建 照片墙 和 视频墙

下载 Github:https://github.com/super-tongyao/wall 国内仓库&#xff08;不推荐&#xff0c;只做加速访问&#xff0c;无编译包和发行版&#xff0c;以github仓库为准&#xff09;&#xff1a;https://gitee.com/Super_TongYao/wall 推荐github仓库&#xff0c;下载最新版…

演化算法:乌鸦搜索算法 (Crow Search Algorithm)

前言 如果你对这篇文章感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 在机器学习中&#xff0c;我们所要优化的问题很多时候难以求导&#xff0c;因此通常会采用一些演化算法&#xff08;又称零…

C++——模板

文章目录1 泛型编程2 函数模板2.1 函数模板概念2.2 函数模板格式2.3 函数模板的实例化2.3.1 隐式实例化2.3.1.1 定义2.3.1.2 代码演示2.3.1.3 运行结果2.3.1.4 缺点2.3.2 显式实例化2.3.2.1 格式2.3.2.2 代码演示2.3.2.3 运行结果2.4 模板参数的匹配原则2.4.12.4.22.4.33 类模板…

并发编程的三大挑战之原子性及其解决方案

目录 一、原子性问题 1、带来原子性问题的原因 2、如何解决线程切换带来的原子问题 2.1、使用synchronized关键字来保证 2.2、使用CAS来保证原子性 2.3、使用lock锁来保证 一、原子性问题 1、带来原子性问题的原因 线程切换是带来原子的根本原因&#xff0c;java的并发程…

proteus光敏电阻电路的arduino仿真

虽然Fritzing0.9.10有了仿真的功能&#xff0c;但都是测试板&#xff0c;能够仿真的很有限&#xff0c;所以还是要借助proteus来仿真。这里&#xff0c;我们来实先一个简单的光明电阻的仿真电路。本篇博文&#xff0c;重点演示proteus仿真arduino光敏电阻&#xff0c;arduino采…

Kerberos 域委派攻击之基于资源的约束性委派

CSDN自动迁移博客文章注意区别&#xff1a;约束性委派 不能跨域进行委派&#xff0c;基于资源的约束性委派可以跨域和林如果约束性委派&#xff0c;必须拥有 SeEnableDelegationPrivilege 权限&#xff0c;该特权是敏感的&#xff0c;通常仅授予域管理员。为了使用户/资源更加独…

DDD领域驱动设计初探

DDD 强调领域模型要兼顾业务和技术两个视角。 我们怎么用一套系统化的方法&#xff0c;抽丝剥茧、一步一步地把需求落实到代码呢&#xff1f;咱们看看下面这张图&#xff0c;它表示了领域驱动设计中的主要流程。 领域驱动设计主要的开发流程你可以看到&#xff0c;在整个开发流…

IDEA 实现热部署(社区版)

前言 为什么要热部署&#xff1f; 开发环境下&#xff0c;我们经常对项目代码进行变动&#xff0c;如果每次都重新启动应用会浪费我们大量时间&#xff0c;为此就产生了热部署的方案&#xff0c;可以在不重启的情况下使用新代码。 热部署为了解决的问题有两个: 在开发的时候…

华为网工入门之eNSP小实验(6)--OSPF(一)基础概念及单区域配置

OSPF OSPF属于典型的链路状态路由协议链路状态路由协议的四个步骤: 1.相邻的建立邻居关系2.邻居间的链路间的状态信息(LSA)交互和同步LSDB(链路状态数据库)3.优选路径运算 (SPF算法计算)4.根据最优路径生成路由表项加载到路由表 目前针对ipv4协议使用的是OSPF Version 2(RFC23…

测试测开面试要知道的那些事01

列表与元组的区别列表是动态数组&#xff0c;它们可变且可以重设长度&#xff08;改变其内部元素的个数&#xff09;。元组是静态数组&#xff0c;它们不可变&#xff0c;且其内部数据一旦创建便无法改变。元组缓存于Python运行时环境&#xff0c;这意味着我们每次使用元组时无…

JAVA进阶 —— 集合进阶

目录 一、 双列集合 二、 Map 1. Map的常见API 2. Map的遍历方式 2.1 第一种遍历方式&#xff1a;键找值 2.2 第二种遍历方式&#xff1a;键值对 2.3 第三种遍历方式&#xff1a;Lambda表达式 三、 Map的三种实现类 1. HashMap 2. LinkedHashMap 3. TreeMap 3.1 练…