【ZooKeeper学习笔记】
1. ZooKeeper基本概念
Zookeeper官网:https://zookeeper.apache.org/index.html
- Zookeeper是Apache Hadoop项目中的一个子项目,是一个树形目录服务
- Zookeeper翻译过来就是动物园管理员,用来管理Hadoop(大象)、Hive(蜜蜂)、Pig(小猪)的管理员,简称zk
- Zookeeper的本质是一个分布式的、开源的、提供分布式应用程序协调服务的组件
- Zookeeper提供的主要功能有:
- 配置管理
- 分布式锁
- 集群管理
2. ZooKeeper常用命令
2.1 ZooKeeper数据模型
在正式介绍Zookeeper的常用命令之前,我们先来了解一下Zookeeper的相关数据模型:
- Zookeeper的是一个树形目录服务,其数据模型与unix文件系统目录树类似,是一个层次化的结构
- 这里面的每一个节点都被称为ZNode,每个节点上都会保存自己的数据以及元数据信息
- 节点也可以拥有子节点,同时允许少量数据(1MB)存储在该节点之下
- 节点类型大致可以分为如下四类:
- PERSISTENT:持久化节点
- EPHEMERAL:临时节点 -e
- PERSISTENT_SEQUENTIAL:持久化顺序节点 -s
- EPHEMERAL_SEQUENTIAL:临时顺序节点 -e -s
2.2 ZooKeeper常用命令
Zookeeper是一个常见的客户端-服务器模型,我们可以使用命令行或者JavaAPI的方式充当客户端进行访问,其架构如下图所示:
- 服务端命令:
./zkServer.sh start
启动zookeeper服务
./zkServer.sh status
查看zookeeper服务运行状态
./zkServer.sh restart
重启zookeeper服务
./zkServer.sh stop
关闭zookeeper服务
- 客户端命令:
./zkCli.sh -server ip:port
连接指定的zookeeper服务(如连接本地可忽略选项直接使用./zkCli.sh)
quit
退出客户端交互界面
help
查看命令帮助
ls 目录
查看指定目录下的znode节点
ls -s 目录
查看节点详细信息
create znode [value]
创建znode节点(可以携带data)
create znode -e [value]
创建临时节点(会话结束后消失)create znode -s [value]
创建顺序节点
get znode
查看节点携带数据
set znode value
设置节点数据
delete znode
删除指定的znode节点(必须为空)
deleteall znode
删除指定的znode节点及其子节点
2.3 ZooKeeper的JavaAPI操作
2.3.1 Curator介绍
Curator:是一个Zookeeper的Java客户端库
- 常见的Zookeeper Java客户端有如下几种:
- 原生JavaAPI
- ZkClient
- Curator
- Curator的目标就是简化Zookeeper客户端的使用
- Curator项目最初有Netflix公司研发,后来捐给了Apache基金会,成为顶级项目
Curator官网:http://curator.apache.org/
2.3.2 Curator API操作
2.3.2.1 建立连接
我们可以使用CuratorFrameworkFactory
静态工厂类进行创建,可以通过如下两种方式配置:
- 使用
newClient()
方法 - 使用
build()
方法
下面我们就给出对应两种代码的实现方式:
newClient:
/*** ZooKeeper测试类*/
public class ZooKeeperTest {private CuratorFramework client = null;@Beforepublic void initByNewClient() {CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181",3000,3000,new ExponentialBackoffRetry(3000, 1));this.client = client;this.client.start();}
}
build:
/*** ZooKeeper测试类*/
public class ZooKeeperTest {private CuratorFramework client = null;@Beforepublic void init() {CuratorFramework client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181").sessionTimeoutMs(3000).connectionTimeoutMs(3000).retryPolicy(new ExponentialBackoffRetry(3000, 1)).namespace("").build();client.start();this.client = client;}
}
其中各个配置项含义如下:
connectString
:连接字符串,配置服务器地址,格式为ip:portsessionTimeoutMs
:会话超时时间connectionTimeoutMs
:连接超时时间retryPolicy
:重试策略namespace
:设置根目录位置
2.3.2.2 创建节点
创建节点有如下常见的四种方式:
Case1:创建节点(不携带数据)
@Test
public void testCreate1() throws Exception {String path = client.create().forPath("/app1");System.out.println(path);
}
Case2:创建节点(携带数据)
@Test
public void testCreate2() throws Exception {String path = client.create().forPath("/app2", "curator java api".getBytes());System.out.println(path);
}
Case3:创建多级节点
@Test
public void testCreate4() throws Exception {client.create().creatingParentsIfNeeded().forPath("/test/test1/test2");
}
Case4:创建节点并指定类型
@Test
public void testCreate3() throws Exception {client.create().withMode(CreateMode.EPHEMERAL).forPath("/app3");client.create().withMode(CreateMode.PERSISTENT).forPath("/app4");client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/app5");client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/app6");
}
2.3.2.3 删除节点
删除节点有如下常见的两种方式:
Case1:删除节点(不含子节点)
@Test
public void testDelete() throws Exception {client.delete().forPath("/app1");
}
Case2:删除节点(递归删除子节点)
@Test
public void testDeleteAll() throws Exception {client.delete().deletingChildrenIfNeeded().forPath("/test");
}
2.3.2.4 查询节点
查询节点有如下常见的三种方式:
Case1:查询子节点信息
@Test
public void testGetChildren() throws Exception {List<String> childrenList = client.getChildren().forPath("/");System.out.println(childrenList);
}
Case2:查询节点数据
@Test
public void testGetData() throws Exception {byte[] bytes = client.getData().forPath("/app2");System.out.println("data: " + new String(bytes));
}
Case3:查询节点详细信息
@Test
public void testGetData3() throws Exception {Stat stat = new Stat();client.getData().storingStatIn(stat).forPath("/app2");System.out.println(stat);
}
2.3.2.5 修改节点
修改节点有如下常见的两种方式:
Case1:修改节点数据
@Test
public void testSetData() throws Exception {Stat stat = client.setData().forPath("/app1", "some data".getBytes());System.out.println(stat);
}
Case2:修改节点数据(带有版本号)
@Test
public void testSetData2() throws Exception {Stat stat = new Stat();client.getData().storingStatIn(stat).forPath("/app2");int version = stat.getVersion();System.out.println(version);client.setData().withVersion(version).forPath("/app2", "set with version".getBytes());
}
3. ZooKeeper的事件监听机制
Watcher事件监听机制:
- ZooKeeper允许用户在指定节点上注册一些Watcher,当一些特定事件发生时,ZooKeeper就会将事件通知给对其感兴趣的客户端,这是ZooKeeper提供分布式协调服务的重要特性
- ZooKeeper引入了Watcher机制来实现发布 / 订阅功能,能够让多个订阅者同时监听某一个对象,当一个对象状态发生变化时就会通知所有订阅者
- ZooKeeper提供原生Watcher的方式,但是比较麻烦,因此Curator使用Cache数据结构进行了优化实现监听机制
- Curator提供了如下三种Cache:
- NodeCache:只监听某一个指定的节点变化
- PathChildrenCache:监控一个节点的所有子节点
- TreeCache:监控整个树上的节点,类似于前两者的组合
3.1 Node Cache
代码实现:
@Test
public void testCuratorCache() throws Exception {NodeCache cache = new NodeCache(client, "/app1");cache.getListenable().addListener(new NodeCacheListener() {@Overridepublic void nodeChanged() throws Exception {System.out.println("监听到节点变化...");}});cache.start();while (true) {}
}
3.2 PathChildren Cache
代码实现:
@Test
public void testPathChildrenCache() throws Exception {PathChildrenCache cache = new PathChildrenCache(client, "/app1", true);cache.getListenable().addListener(new PathChildrenCacheListener() {@Overridepublic void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {System.out.println("监听到子节点变化...");PathChildrenCacheEvent.Type type = pathChildrenCacheEvent.getType();if (type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)) {System.out.println("监听到子节点数据变化...");System.out.println("更新后数据: " + pathChildrenCacheEvent.getData().getData());}}});cache.start();while (true) {}
}
3.3 Tree Cache
代码实现:
@Testpublic void testTreeCache() throws Exception {TreeCache cache = new TreeCache(client, "/app1");cache.getListenable().addListener(new TreeCacheListener() {@Overridepublic void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {System.out.println("监听到节点发生变化...");System.out.println(treeCacheEvent);}});cache.start();while (true) {}}
4. ZooKeeper分布式锁
4.1 ZooKeeper分布式锁原理
- 核心思想:当用户获取到锁时就创建节点,使用完锁就删除节点
- 每当一个用户想要获取锁时就在
/lock
节点下创建一个 **临时顺序 **节点 - 然后获取
/lock
节点下的全部子节点,如果发现当前节点编号是最小的,则该节点对应的客户端获取到锁,使用完锁后,删除该节点 - 如果发现节点编号不是最小的,则对前一个比自己小的编号节点,并注册事件监听器,监听删除事件
- 如果后续发现比自己小的节点被删除,则客户端会接收到来自ZooKeeper的通知,然后再次判断所对应节点编号是否是最小的,重复上述步骤
注意:这里创建临时节点是因为防止获取到锁的客户端宕机了,进而导致锁永远不会被删的情况;这是创建顺序节点是方便编号的排序
Cutator提供了下面五种分布式锁的方式:
- InterProcessMutex(分布式可重入排他锁)
- InterProcessSemaphoreMutex(分布式不可重入排他锁)
- InterProcessReadWriteLock(分布式读写锁)
- InterProcessMutliLock(将多个锁作为单个实体管理的容器)
- InterProcessSemaphoreV2(共享信号量)
4.2 分布式锁实战(模拟12306抢票)
代码如下:
package org.example;import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;import java.util.concurrent.TimeUnit;public class ZooKeeperLockTest {private static int tickets = 10; // 票数public static void main(String[] args) {// 建立连接CuratorFramework client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181").sessionTimeoutMs(3000).connectionTimeoutMs(3000).retryPolicy(new ExponentialBackoffRetry(3000, 1)).namespace("").build();client.start();// 获取分布式锁InterProcessMutex lock = new InterProcessMutex(client, "/lock");Thread t1 = new Thread(() -> {while (true) {try {boolean hasLock = lock.acquire(3, TimeUnit.SECONDS);if (hasLock && tickets > 0) {// 不断抢票System.out.println("线程" + Thread.currentThread().getName() + "抢到了当前第" + tickets + "张票");tickets--;if (tickets <= 0) {break;}}} catch (Exception e) {throw new RuntimeException(e);} finally {try {lock.release();} catch (Exception e) {throw new RuntimeException(e);}}}}, "携程");Thread t2 = new Thread(() -> {while (true) {try {boolean hasLock = lock.acquire(3, TimeUnit.SECONDS);if (hasLock && tickets > 0) {// 不断抢票System.out.println("线程" + Thread.currentThread().getName() + "抢到了当前第" + tickets + "张票");tickets--;if (tickets <= 0) {break;}}} catch (Exception e) {throw new RuntimeException(e);} finally {try {lock.release();} catch (Exception e) {throw new RuntimeException(e);}}}}, "飞猪");t1.start();t2.start();}
}
5. ZooKeeper集群管理
Leader选举过程:
- ServerId:服务器ID
比如有三台服务器,编号分别是1,2,3。则编号越大在选择算法中的权重就越大
- Zxid:数据ID
服务器中存放的数据ID越大,值越大说明更新的越频繁,则在选择算法中的权重就越大
- 在Leader选举的过程中如果某台ZooKeeper超过了半数选票,则直接当选为Leader
相关文章:

【ZooKeeper学习笔记】
1. ZooKeeper基本概念 Zookeeper官网:https://zookeeper.apache.org/index.html Zookeeper是Apache Hadoop项目中的一个子项目,是一个树形目录服务Zookeeper翻译过来就是动物园管理员,用来管理Hadoop(大象)、Hive&…...

220V降5V芯片输出电压电流封装选型WT
220V降5V芯片输出电压电流封装选型WT 220V降5V恒压推荐:非隔离芯片选型及其应用方案 在考虑220V转低压应用方案时,以下非隔离芯片型号及其封装形式提供了不同的电压电流输出能力: 1. WT5101A(SOT23-3封装)适用于将2…...
AWS S3 基本概念
AWS S3 基本概念 引言什么是 AWS S3S3 应用S3 的核心概念 引言 最近工作中有接触到 S3,往 S3 写入数据,从 S3 访问数据,所以花点时间整理一下有关 S3 的基本概念。 什么是 AWS S3 AWS S3 (Amazon Simple Storage Service) 是一个由 Amazon…...
[XCUITest] 处理iOS权限点击授权 有哪些权限?
位置权限 (Location Permission) app.addUIInterruptionMonitor(withDescription: "Location Permission Dialog") { (alert) -> Bool in if alert.buttons["Allow While Using App"].exists { alert.buttons["Allow While Using App"].tap(…...
宪法学学习笔记(个人向) Part.5
宪法学学习笔记(个人向) Part.5 4. 公民基本权利和义务 4.1 公民🌸 概念 是指具有某个国家国籍的自然人; 【拓展】国籍:在宪法上是指一个人隶属于某个国家的法律上的身份🌸 ; 取得方式 出生国籍 因出生而获得的国籍&a…...

C语言的指针与数组
函数定义 参考书籍章节9.7 无论函数定义的参数是数组还是指针,在编译的时候,编译器都将在栈上开辟一个空间存放入参的地址,换句话说,也就是在函数内部都当做指针处理。 #include <stdio.h> #include <stdlib.h>char g…...

计算机图形学入门28:相机、透镜和光场
1.前言 相机(Cameras)、透镜(Lenses)和光场(Light Fields)都是图形学中重要的组成部分。在之前的学习中,都是默认它们的存在,所以现在也需要单独拿出来学习下。 2.成像方法 计算机图形学有两种成像方法,即合成(Synthesis)和捕捉(Capture)。前…...
Swift 基于Codable协议使用
Codable协议 继承自 Decodable & Encodable // // Test1.swift // TestDemo // // Created by admin on 2024/7/9. // import Foundationstruct Player{var name:Stringvar highScore:Int 0var history:[Int] []var address:Address?var birthday:Date?init(name: St…...
conda激活的虚拟环境的python版本不对应
这个大坑,要看看虚拟环境下envs下有没有bin文件夹 python -Vecho $PATH镜像源的问题,参考...

深度学习概览
引言 深度学习的定义与背景 深度学习是机器学习的一个子领域,涉及使用多层神经网络分析和学习复杂的数据模式。深度学习的基础可以追溯到20世纪80年代,但真正的发展和广泛应用是在21世纪初。计算能力的提升和大数据的可用性使得深度学习在许多领域取得…...

什么是白盒测试中的静态测试?其包含哪些过程和方法?
文章目录 前言一、文档审查二、软件静态分析1.编码规范检查2.软件质量度量 三、代码审查与代码走查1.代码审查2.代码走查 总结 前言 软件白盒测试中的静态测试是指不运行被测软件,仅通过分析或检查等手段达到检测的目的。在软件白盒测试中,静态测试常通…...
搭建一个高并发的Web商品推荐系统,如何涉及软件架构?
搭建一个高并发的Web商品推荐系统,如何涉及软件架构 在搭建一个高并发的Web商品推荐系统时: 微服务架构: 为了支持高并发,我们可以采用微服务架构,将系统拆分成小型、独立的服务,每个服务专注于特定的功…...
今日科技圈最新时事新闻(2024年7月12日
一、智能硬件与电子产品 小米Redmi G Pro 2024游戏本新版本发布 发布时间:7月12日上午10点产品亮点: 搭载英特尔酷睿i7-14650HX处理器,拥有16个核心和24个线程,性能释放高达130W。配备140W满血释放的RTX 4060显卡,提…...

jenkins系列-09.jpom构建java docker harbor
本地先启动jpom server agent: /Users/jelex/Documents/work/jpom-2.10.40/server-2.10.40-release/bin jelexjelexxudeMacBook-Pro bin % sh Server.sh start/Users/jelex/Documents/work/jpom-2.10.40/agent-2.10.40-release/bin jelexjelexxudeMacBook-Pro bin % ./Agent.…...

构造+贪心,CF 432E,Square Tiling
一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - 432E - Codeforces 二、解题报告 1、思路分析 很简单的一个构造题 考虑字典序从左到右从上到下,所以我们正常遍历 对于当前格子如果空闲,那么找到一个能填的最小字符 然…...

【Linux】任务管理
这个任务管理(job control)是用在bash环境下的,也就是说:【当我们登录系统获取bashshell之后,在单一终端下同时执行多个任务的操作管理】。 举例来说,我们在登录bash后,可以一边复制文件、一边查…...
计算机网络——常见问题汇总
1. introduction 1.1 Explain what a communication protocol is and why its important. A communication protocol is a set of rules and conventions(公约) that govern(统治) how data is transmitted and received between devices(设备), systems, or entities in a ne…...

Linux的世界 -- 初次接触和一些常见的基本指令
一、Linux的介绍和准备 1、简单介绍下Linux的发展史 1991年10月5日,赫尔辛基大学的一名研究生Linus Benedict Torvalds在一个Usenet新闻组(comp.os.minix)中宣布他编制出了一种类似UNIX的小操作系统,叫Linux。新的操作系统是受到另一个UNIX的…...
[AI 大模型] Meta LLaMA-2
文章目录 [AI 大模型] Meta LLaMA-2简介模型架构发展新技术和优势示例 [AI 大模型] Meta LLaMA-2 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yYHlT342-1720705768360)(https://i-blog.csdnimg.cn/direct/9ddc783e01bf48c3bc784a584339003f.jpeg…...

Python3.6.6 OpenCV 将视频中人物标记或者打马赛克或加图片并保存为不同格式
1、轻松识别视频人物并做出标记 需安装face_recongnition与dlib,过程有点困难,还请网上查找方法 import face_recognition import cv2 #镜像源 -i https://pypi.mirrors.ustc.edu.cn/simple # 加载视频 video_file E:\\videos\\1.mp4 video_capture …...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...

相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...
数据库正常,但后端收不到数据原因及解决
从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...