【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 …...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
