Zookeeper的学习笔记
Zookeeper概念
Zookeeper是一个树形目录服务,简称zk。
Zookeeper是一个分布式的、开源的分布式应用程序的协调服务
Zookeeper提供主要的功能包括:配置管理,分布式锁,集群管理
Zookeeper命令操作
zk数据模型

zk中的每一个节点都被称为:ZNode,每个节点上都会保存自己的数据和节点信息。节点可以拥有子节点,同时也允许少量(1MB)数据存储在该节点之下
节点可以分为四大类:
- PERSISTENT 持久化节点
- EPHEMERAL 临时节点:-e
- PERSISTENT_SEQUENTIAL持久化顺序节点:-s
- EPHEMERAL_SEQUENTIAL临时顺序节点:-es
zk服务端命令
启动zk服务
./zkServer.sh start
zk查看zk服务状态
./zkServer.sh status
停止zk服务
./zkServer.sh stop
重启zk服务
./zkServer.sh restart
zk客户端命令
zkCli.sh连接ZooKeeper服务命令
./zkCli.sh [-server ip地址:2181] (如果是连接本机zk服务,可以省略[]中的内容)
查看zk中的节点
ls /[节点名称]
创建节点方法
create [节点类型] /父节点 [存储信息] (存储信息可以不写)
临时节点创建 -e(服务器关闭,下次连接就会删除)
顺序节点创建 -s
临时顺序节点创建 -es
查看节点存储信息的方法
get /目录
ls -s 是查询结点状态信息
设置节点数据
set /目录 存储信息
删除节点
delete /目录(只能删除空目录)
deleteall /目录(有子结点也可以删除)
在创建节点时,如果没有指定存储数据,那么默认存储的数据是当前服务器的ip地址

Curator介绍
CUrator是Zookeeper的Java客户端库,常见的Zookeeper Java API有三种:
- 原生Java API
- ZkClient
- Curator
相较于原生Java API,Curator使用较为简单,其次,高版本的Curator可以向下兼容zk,但zk无法向下兼容Curator
Curator API常用操作
连接zk服务
一共有两种连接客户端的方式,一种是通过newClient(),一种是通过Builder链式编程创建客户端对象
@Test
public void test() throws Exception {//指定重试策略RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);//第一种连接zk方式/*参数1:指定需要连接的zk地址与端口,如果是集群模式,使用,分隔开参数2:会话超时时间参数3:连接超时时间参数4:重试策略*/CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.116.131:2181", 60 * 1000, 15 * 1000, retryPolicy);client.start();//第二种连接方式,可以指定namespace,其实是指定根目录(此后该客户端对象的curd操作都会在指定的根目录下进行)CuratorFramework client2 = CuratorFrameworkFactory.builder().connectString("192.168.116.131:2181").sessionTimeoutMs(60 * 1000).connectionTimeoutMs(15 * 1000).retryPolicy(retryPolicy).namespace("zmt").build();client2.start();
}
创建节点
创建节点默认创建节点类型为持久化,返回结果为路径,如果不指定节点存储类型,那么默认存储客户端的ip地址
@Test
public void testCreate() throws Exception {//如果不指定参数2,那么该节点的存储数据为客户端的ip地址String path = client.create().forPath("/app1","zhangsan".getBytes());System.out.println(path);//我们可以通过指定withMode来确定需要创建的节点类型,参数为枚举类client.create().withMode(CreateMode.EPHEMERAL).forPath("/app2");//创建多级节点,创建父结点,如果需要client.create().creatingParentsIfNeeded().forPath("/app3/p1");
}
查询节点
我们可以查询节点的存储信息,也可以查询节点的子节点信息,也可以查询节点的状态信息
@Test
public void testGet() throws Exception {//获取节点存储信息byte[] data = client.getData().forPath("/app1");System.out.println(new String(data));//获取子节点信息List<String> list = client.getChildren().forPath("/app3");System.out.println(list);//获取节点状态信息Stat status = new Stat();client.getData().storingStatIn(status).forPath("/app1");System.out.println(status);
}
修改节点
因为可能存在多个客户端连接同一个zookeeper,因此可能会出现修改节点数据时,其他节点也在修改的问题,因此为了避免出现同时修改同一个数据的情况发生,我们应该先获取数据的版本,然后修改数据时根据数据的版本是否一致再决定是否进行修改。
@Test
public void testSetForVersion() throws Exception {int version;Stat stat = new Stat();client.getData().storingStatIn(stat).forPath("/app1");version = stat.getVersion();System.out.println(version);client.setData().withVersion(version).forPath("/app1","lisi".getBytes());
}
删除节点
一般我们都要添加guaranteed()方法来避免网络问题产生的删除失败的问题
@Test
public void testDelete() throws Exception {//删除单个节点client.delete().forPath("/app1");//删除多级节点client.delete().deletingChildrenIfNeeded().forPath("/app3");//删除失败进行重试,直到删除成功//比如说网络不好,导致删除失败,可以重复进行删除client.delete().guaranteed().forPath("/app2");//删除回调client.delete().guaranteed().inBackground(new BackgroundCallback() {//执行回调方法@Overridepublic void processResult(CuratorFramework client, CuratorEvent event) throws Exception {System.out.println("节点被删除");System.out.println(event);}}).forPath("/app4");
}
Watch事件监听
zk运行用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,zk服务端会将事件通知到感兴趣的客户端上去,该机制是zk实现分布式协调服务的重要特性。
zk中引入了Watch机制来实现了发布订阅功能,能够让多个订阅者同时监听某一个对象,当一个对象自身状态发生变化时,会通知所有的订阅者
zk提供了3种Watcher:
- NodeCache:只监听一个特定结点
- PathChildrenCache:监控一个Znode的子节点
- TreeCache:前两个结合,监听自己和自己所有子节点
NodeCache的简单使用
@Test
public void testNodeCache() throws Exception {NodeCache nodeCache = new NodeCache(client, "/app1");nodeCache.getListenable().addListener(new NodeCacheListener() {@Overridepublic void nodeChanged() throws Exception {System.out.println("节点发生变化");//获取节点变化后的值byte[] data = nodeCache.getCurrentData().getData();System.out.println(new String(data));}});nodeCache.start();while (true){}
}
PathChildrenCache的简单使用
@Test
public void testChildrenCache() throws Exception {PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/", true);pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {@Overridepublic void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {System.out.println("节点发生变化");System.out.println(pathChildrenCacheEvent);PathChildrenCacheEvent.Type type = pathChildrenCacheEvent.getType();if (type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){//如果是update事件byte[] data = pathChildrenCacheEvent.getData().getData();System.out.println(new String(data));}}});pathChildrenCache.start();while (true) {}
}
TreeCache的简单使用
@Test
public void testTreeCache() throws Exception {TreeCache treeCache = new TreeCache(client,"/");treeCache.getListenable().addListener(new TreeCacheListener() {@Overridepublic void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {System.out.println("数据发生变化");System.out.println(treeCacheEvent);}});treeCache.start();while (true) {}
}
分布式锁
作用于多个JVM环境,保证多线程安全。
实现分布式锁的原理:当客户端要获取锁时,创建节点,使用完锁,删除该节点
- 客户端获取锁时,在lock节点下创建临时顺序结点
- 然后客户端获取lock下面所有的子节点,如果发现自己创建的子节点序号最小,那么就认为该客户端获取到了锁。使用完后把节点删除
- 如果不是最小的结点,说明此时自己还没有获取到锁,此时客户端需要找到比自己小的哪个结点,同时对其注册事件监听器,监听删除事件。
- 如果比自己小一个的结点被删除,则客户端的Watcher会收到通知,此时再次判断自己的结点是否最小,如果不是,重复以上步骤
采取临时节点是为了避免客户端在获取到锁之后处理业务时宕机,当客户端宕机之后,会话结束,临时节点会自动删除

Curator实现分布式锁API
一共有五种方案:
- 分布式排他锁
- 分布式可重入排他锁
- 分布式读写锁
- 将多个锁作为单个实体管理的容器
- 共享信号量
一个简单的售票案例
public class Ticket12306 implements Runnable {//模拟十张票private int num = 10;//分布式可重入式锁private InterProcessMutex lock;public Ticket12306() {RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 2);CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.116.131:2181").connectionTimeoutMs(60*1000).sessionTimeoutMs(15*1000).retryPolicy(retryPolicy).build();client.start();lock = new InterProcessMutex(client, "/lock");}@Overridepublic void run() {while (true) {try {lock.acquire(3, TimeUnit.SECONDS);if (num > 0) {Thread.sleep(100);System.out.println(Thread.currentThread().getName() + "出售了一张票:" + num);num--;}} catch (Exception e) {System.out.println("我出错了??");e.printStackTrace();} finally {try {lock.release();} catch (Exception e) {e.printStackTrace();}}}}
}
测试
public class TestTicket {@Testpublic void testTicket() throws Exception {Ticket12306 ticket = new Ticket12306();Thread t1 = new Thread(ticket, "携程");Thread t2 = new Thread(ticket, "飞猪");t1.start();t2.start();while(true){}}
}
实现分布式锁的核心代码如下
new 一个锁类型对象lock
lock.acquire()//获取锁
需要上锁的功能
lock.release();//释放锁
相关文章:
Zookeeper的学习笔记
Zookeeper概念 Zookeeper是一个树形目录服务,简称zk。 Zookeeper是一个分布式的、开源的分布式应用程序的协调服务 Zookeeper提供主要的功能包括:配置管理,分布式锁,集群管理 Zookeeper命令操作 zk数据模型 zk中的每一个节点…...
leetcode2两数加和问题(链表)
题目思路: ①创建一个int类型的局部变量,用来存储两个结点的Val值。 ②判断该Val值与10求余(mod)后是否大于0,如果大于0, 则需要在下一个结点进位。 ③最关键的步骤:实现l1,l2结点数值相加后构建新的存储求和后的结点࿰…...
VSCode中配置prettier和ESLint
文章目录 了解ESLint和Prettier的作用prettier配置ESLint配置常见问答ESLint 和Prettier 有什么区别?为什么我应该同时使用ESLint 和Prettier?在使用ESLint 和Prettier 时,有可能出现它们之间的规则冲突吗?我已经在项目中使用了ES…...
如何将本地websocket发布至公网并实现远程访问服务端
文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…...
分享 | 软件测试的基本流程是什么?软件测试流程详细介绍
软件测试 软件测试和软件开发一样,是一个比较复杂的工作过程,如果无章法可循,随意进行测试势必会造成测试工作的混乱。为了使测试工作标准化、规范化,并且快速、高效、高质量地完成测试工作,需要制订完整且具体的测试…...
浮点数的转换--IEEE 754
IEEE754标准是一种浮点数表示标准,一般分为 单精度(32位的二进制数);双精度(64位的二进制数) 根据国际标准IEEE754,任意一个二进制浮点数V可以表示为下面形式: V (-1)^s *&#…...
若依框架介绍
RuoYi(若依)是一款基于Spring Boot、Spring Cloud等开源框架搭建的企业级开发平台,旨在提供全面的解决方案,简化企业级应用开发,提高开发效率。 主要特点: 1. 模块化设计 RuoYi采用模块化的设计࿰…...
iMazing2024免费版iOS移动设备管理软件
以自己的方式管理iPhone,让备受信赖的软件为您传输和保存音乐、消息、文件和数据。安全备份任何 iPhone、iPad 或 iPod touch。iMazing 功能强大、易于使用,称得上是 Mac 和 PC 上最好的 iOS 设备管理器。 正在为iTunes繁琐的操作发愁?设备数…...
Zookeeper整合Java实战,不同客户端使用汇总
Java学习面试指南:https://javaxiaobear.cn ZooKeeper应用的开发主要通过Java客户端API去连接和操作ZooKeeper集群。可供选择的Java客户端API有: ZooKeeper官方的Java客户端API。 第三方的Java客户端API,比如Curator。 ZooKeeper官方的客户…...
【python】Ubuntu下安装spyder及matplotlib中文显示
一、查看Ubuntu版本 $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy尝试用cat /etc/debian_version命令,竟然可以显示出来Debian的版本。 $ cat /etc/debian_version …...
《运维人员的未来:IT界的“万金油“如何继续闪耀光芒》
文章目录 每日一句正能量前言35岁被称为运维半衰期,究竟为何?如何顺利过渡半衰期运维的职业发展路径后记 每日一句正能量 凡事顺其自然,遇事处于泰然,得意之时淡然,失意之时坦然,艰辛曲折必然,历…...
ip addr和ifconfig
ip addr可以显示更多信息,包括为启动的网络驱动如wlan,而ifocnfig只显示在线的驱动。若wlan是down的,则ip addr会显示信息,ifconfig不会显示信息。 ip addr: ifconfig:...
Crow:Middlewares 庖丁解牛7 after_handlers_call_helper
Crow:Middlewares 庖丁解牛6 middleware_call_helper-CSDN博客 介绍了对插件before_handle的调用 当完成了detail::middleware_call_helper的调用后,如果没有在before_handle中设置req被终止处理,也就是 if (!res.completed_) {need_to_call_after_handlers_ = true;handler…...
ts相关笔记(extends、infer、Pick、Omit)
最近刷了本ts小册,对一些知识点做下笔记。 extends extends 是一个关键字,用于对类型参数做一些约束。 A extends B 意味着 A 是 B 的子类型,比如下面是成立的 ‘abc’ extends string599 extends number 看下面例子: type …...
8.21 PowerBI系列之DAX函数专题-帕累托分析
需求 实现 1 按商品小类累积 var rollup_sales calculate(//计算当前累计销售额 [销售额], filter(allselected(order_2[产品小类]),sum(order_2[订单金额])<[销售额]) ) //按小类累积金额,filter内的销售额为选中的各小类的销售额 //金额从大到小累积,用&l…...
结构体-2-测试排名
22-结构体-2-测试排名 [命题人 : 外部导入] 时间限制 : 1.000 sec 内存限制 : 128 MB 题目描述 为了提升同学们的编程能力,老师们会在平时进行C语言的上机测试,了解班上同学的学习情况,对于一些测试成绩较差的同学,老师会进行督促…...
LeetCode刷题---快乐数
解题思路 该题的解题思路为使用哈希表来存储每次平方的和的结果,看是否有重复的数,如果存在第n次的平方和的数和第i次(i<n)平方和的数想等,那么它就不是一个快乐数。否则,则为快乐数。 代码实现: public boolean i…...
web前端游戏项目-辨色大比拼【附源码】
web前端游戏项目-辨色大比拼【附源码】 《辨色大比拼》是一个旨在测试和提升玩家颜色识别能力的在线游戏。在游戏中,玩家将通过辨识颜色来解谜并推进游戏进程。辨色大比拼也是一个寓教于乐的游戏,它不仅提供了一个有趣的辨色挑战,还能帮助玩…...
MongoDB操作_数据库_集合
.......................................................................................................................................................... 三、MongoDB操作 3.1 数据库操作 一个mongodb中可以建立多个数据库。 MongoDB的默认数据库为"test…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
