ZooKeeper 相关概念以及使用小结 zookeeper用处
yuyutoo 2024-10-16 15:46 9 浏览 0 评论
Dubbo 通过注册中心在分布式环境中实现服务的注册与发现,而注册中心通常采用 ZooKeeper,研究注册中心相关源码绕不开 ZooKeeper,所以学习了 ZooKeeper 的基本概念以及相关 API 操作。
ZooKeeper 相关概念
session
客户端与服务端采用 TCP 长连接,服务端在为客户端创建 Session 会分配一个唯一 sessionId。在 Session timeout 时间内,客户端可以向服务端发送请求以及接受 watcher 事件通知。
数据结构
Zookeeper 将所有数据存储在内存中,数据模型是一棵树(Znode Tree),由斜杠(/)的进行分割的路径,就是一个Znode,例如/foo/path1。
Znode
Znode 将会保存数据内容以及相关属性信息。在 Znode 中使用 Stat 数据结保存相关属性信息。Stat 属性中有三种版本信息,分别为 version:当前节点版本信息,cversion:当前节点子节点版本,aversion 当前节点的 ACL 版本。每次发生改动,版本数值将会单调递增。
更新,删除 Znode 可以传入版本数值,如果版本数值不对,将会导致删除/更新失败,这个特性类似于 CAS 操作。
Znode 有以下几种类型:
- 永久节点
一旦创建,将会一直存在,除非手动删除。dubbo 目录节点为永久节点。
- 临时节点
临时节点基于客户端 Session,Session 有效期内将会一直存在,Session 失效,节点将会自动删除。
利用这个机制,Dubbo 服务者创建的节点就是临时节点。如果 Dubbo 服务者程序意外宕机,在 Session 超时之后,也能自动删除服务节点,自动下线有问题的服务。
3 顺序节点
创建顺序节点将会自动在名字后追加整形数字,默认长度为 10 位。顺序节点也分为永久与临时。
利用临时顺序节点,我们可以用来实现分布式锁 七张图彻底讲清楚ZooKeeper分布式锁的实现原理【石杉的架构笔记】。
Watcher 机制
客户端可以在指定节点注册监听器(Watcher),在触发特定事件后,ZooKeeper 服务端会将事件通知到客户端。在 Dubbo 中消费者基于 watcher 机制可以动态感知到新的服务者加入。
ZooKeeper 可以在三种请求中设置监听,分别为:
- getData(),获取节点数据
- getChildren() 获取子节点
- exists() 判断节点是否存在
通知事件类型分为,增删改事件,以及子节点变动事件。
需要注意的是,watcher 通知过一次之后将会失效,若想继续监听通知,需要重新注册。
ZooKeeper 原生 API 操作
ZooKeeper 官方提供 Java API 实现,提供相关操作的方法。
创建连接
ZooKeeper zk=new ZooKeeper("127.0.0.1:2181", 150000, new Watcher() { @Override public void process(WatchedEvent watchedEvent) { System.out.println("已经触发了" + watchedEvent.getType() + "事件"+watchedEvent); } });
创建连接需要传入 ZooKeeper 服务端地址,然后设定 session 超时时间,另外还需要创建一个 Watcher,用于监听连接事件。建立连接之后,就可以使用该客户端操作。
CURD 操作
// 创建永久节点,需要传入 ACL 权限列表,以及指定节点类型 zk.create("/test","test".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.PERSISTENT); // 修改节点值。更新节点值需要传入节点的版本,如果版本与服务端版本不一致,更新失败,类似 CAS 机制。-1 代表不比较节点版本 zk.setData("/test","test1".getBytes(),-1); // 删除节点.删除节点也需要传入节点版本 zk.delete("/test",-1); // 创建临时节点 zk.create("/ephemeral","ephemeral".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.EPHEMERAL);
ZooKeeper 客户端相关 CRUD 操作如上。可以看到相关操作比较繁琐,需要传入参数较多。
watcher
// 在 exists 注册 watcher,创建节点,删除节点,改变节点将会触发回调 zk.exists("/test", new Watcher() { @Override public void process(WatchedEvent event) { System.out.println("回调实例,类型为:"+event.getType()); } }); // 获取节点数据,可以注册 watcher,删除节点以及改变节点数据可以触发回调 zk.getData("/test", new Watcher() { @Override public void process(WatchedEvent event) { System.out.println("回调实例,类型为:"+event.getType()); } },new Stat()); // 获取子节点,注册 watcher,一级子节点变动后将会触发回调 zk.getChildren("/test", new Watcher() { @Override public void process(WatchedEvent event) { System.out.println("回调实例,类型为:"+event.getType()); } });
ZooKeeper API 可以为三种操作注册 watcher,一旦相关节点变动将会触发事件通知。
Curator
从上面代码示例可以看到 ZooKeeper 提供 API 比较复杂且难用。可以使用 Curator 或者 zkclient 这种第三方框架代替原生 API。这类框架封装 ZooKeeper 原生 API,抽象化相关接口,简化操作难度。
dubbo 抽象相关 ZooKeeper 操作,并分别使用 Curator 或者 zkclien 实现。在 dubbo 2.6.1 版本之后将会默认使用 Curator,之前版本默认使用 zkclient 。
下面我们使用 Curator 操作 ZooKeeper 。
建立连接
// 设置重试策略 RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); // 默认 session 超时时间 60 s CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy);
Curator 创建连接与原生 API 大致相关,不过需要设置重试策略,第一次连接失败,Curator 可以重新尝试连接,直到超过最大连接次数。
节点 CURD 操作
// 创建目录节点 client.create().forPath("/test", "123456789".getBytes()); // 创建普通节点 client.create().forPath("/test/normal", "123121".getBytes()); // 修改普通节点内容 client.setData().forPath("/test/normal", "1121231231".getBytes()); // 删除节点 client.delete().forPath("/test/normal"); // 创建临时节点 client.create().withMode(CreateMode.EPHEMERAL).forPath("/ephemeral"); // 创建永久顺序节点 client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/sequential"); // 获取所有子节点 List<String> nodes = client.getChildren().forPath("/parent");
Curator CRUD 操作比较简单,无需设置相关属性参数。
设置监听
Curator 相关监听 API 封装 zookeeper 原生API,内部增加重复注册等功能,从而使监听可以重复使用。
Curator 存在三种类型 API。
- NodeCache:针对节点增删改操作。
- PathChildrenCache:针对节点一级目录下节点增删改监听
- TreeCache:结合 NodeCache 与 PathChildrenCache 操作,不仅可以监听当前节点,还可以监听节点下任意子节点(支持多级)变动。
// `NodeCache`使用方式 NodeCache nodeCache=new NodeCache(client,"/test1",false); nodeCache.getListenable().addListener(new NodeCacheListener() { @Override public void nodeChanged() throws Exception { System.out.println("当前节点:"+nodeCache.getCurrentData()); } }); nodeCache.start(); // PathChildrenCache 使用方式 PathChildrenCache pathChildrenCache=new PathChildrenCache(client,"/test2",false); pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() { @Override public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception { System.out.println(event); } }); pathChildrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE); System.out.println("注册watcher成功..."); // TreeCache 使用方式 TreeCache treeCache=new TreeCache(client,"/tree"); treeCache.getListenable().addListener(new TreeCacheListener() { @Override public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception { System.out.println(event); } }); treeCache.start(); System.out.println("注册watcher成功...");
相关推荐
- pdf,word,ppt,rar,mp4等等文档在线预览
-
背景:移动端的智能化已经被大多数人接受了,但是有时一些文件格式要在移动端打开,需要安装特定的软件才行,这个就是很多人不喜欢的,要看个文档还要下载安装一个app,实在麻烦,那能不能直接在线就预览文件呢具...
- Qt/C++音视频开发69-保存监控pcm音频数据到mp4文件/监控录像
-
一、前言用ffmpeg做音视频保存到mp4文件,都会遇到一个问题,尤其是在视频监控行业,就是监控摄像头设置的音频是PCM/G711A/G711U,解码后对应的格式是pcm_s16be/pcm_alaw...
- 全能下载神器文件蜈蚣体验(全能文件王)
-
文件蜈蚣是一款开源免费的软件,在GitHub上公布了所有源代码,自身非常绿色环保,没有流氓后台也没广告,和莫名弹窗的同行相比,可算得上是一股清流。文件蜈蚣的使用很简单,解压后运行一次其中的exe,完成...
- 支持HLS和mp4在线播放的源码(hls支持的视频编码格式)
-
今天安利的一套在线视频播放源码,它不是安卓端,也不是PC端。你只需要部署一下这个单页面源码即可。使用php+mysql+nginx即可。任何版本都能运行。HLSDOWNLOAD网页打开服务器地址:1...
- 大模型微调知识与实践分享(模具微调结构)
-
一、微调相关知识介绍...
- IOS遇到的几个H5坑、h5键盘弹起遮挡输入框的处理
-
一、IOS遇到的几个H5坑1、ios端兼容input光标高度 问题描述:input输入框光标,在安卓手机上显示没有问题,但是在苹果手机上当点击输入的时候,光标的高度和父盒子的高度一样。例如下图,左...
- 实用技巧:如何在win10中安装没有管理员权限的软件
-
通常,我们可能会遇到需要在Windows10电脑上安装软件,但在该电脑上没有管理员权限的情况,由于不是管理员,所以无权在在电脑上安装软件,这让人非常苦恼。事实上,这是微软专门设计的一个安全功能,它的...
- 基于ENVI的Landsat 7遥感影像处理与多种大气校正方法对比
-
1数据导入与辐射定标关于数据的下载,网络中相关资源很多,这里不再赘述。...
- 在 Python 中为无服务器应用设计安全租户隔离
-
软件即服务(SaaS)已经成为当今一种非常普遍的软件交付方式。虽然这方便了用户访问,而且消除了用户的运营开销,但这也改变了以前的模式,将实现SLA以及现代云原生组织所期望的所有安全和数据隐私要求的...
- 基于JFinal的后台业务框架通用模块
-
jcbase是基于JFinal2.x的后台业务框架通用模块,包括系统权限模块、APP版本管理、日志管理、数据字典等使用的技术要点后端使用JFinal2.x前端页面是基于acev1.3模板改造的,更方便...
- PHOTOSHOP图层技巧(掌握photoshop合并图层技巧)
-
你会图层吗?不会?喔,那你肯定不会PHOTOSHOP。为什么那么说呢?因为图层可以说是PHOTOSHOP的核心,几乎PHOTOSHOP所有的应用都是基于图层的,很多强劲的图像处理功能也是图层所提供的,...
- Cadence Allegro背钻设置详细介绍教程
-
CadenceAllegro背钻设置详细介绍教程...
- Pt中间层显著降低PEM水电解电子传输阻抗
-
在质子交换膜水电解(PEMWE)中,阳极OER的Ir基催化剂成本高昂,成为制约产业化的重要瓶颈。虽然非晶态IrOx具有高OER活性,但其电导率较差、与多孔钛PTL之间接触不良,往往导致催化剂层利用率低...
- GIMP 教程:制作 Duotone 双色调效果
-
今天我们学习如何使用GIMP这款强大的开源图像编辑器,制作流行的Duotone(双色调)效果。Duotone效果的核心原理,是将图像的色调信息映射到两种主要颜色上。通常,一种颜色用于图像的亮部...
- CAD打印的时候线条没了?原来是这些设置出了错
-
每当我们辛辛苦苦绘制完一张图纸之后,打印出图的时候总会出现各种各样的问题,不知道大家有没有遇到这种情况:在预览的时候还一切正常,但是打印出来之后就会发现很多线条都会不见了或者部分缺失。那么到底是怎么一...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)