zookeeper应用之分布式屏障

news/2024/12/28 11:03:27/

分布式系统中某些节点任务当满足某个条件时才允许继续运行,如果不满足则当前节点需要等待。这个时候就需要一个屏障来阻止节点的处理。ZooKeeper Barrier是ZooKeeper提供的一种用于分布式环境中实现同步和协调的机制。具体逻辑就是:

1、检测某个barrier node是否存在

2、如果屏障节点不存在,则屏障不存在可以继续执行

3、如果屏障存在,则需要watcher屏障节点的删除事件,当屏障节点删除当前程序才可继续,删除之前当前程序一直阻塞等待。

这里使用Curator框架API写一个简单的样例程序:

CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new ExponentialBackoffRetry(1000, 3));
client.start();
String path = "/barrier";
//创建屏障节点
client.create().withMode(CreateMode.EPHEMERAL).forPath(path);
//另一个业务执行逻辑,完成后删除屏障
new Thread(()->{try {Thread.sleep(2000);client.delete().forPath(path);} catch (Exception e) {e.printStackTrace();}
}).start();
Object obj = new Object();
//主线程wathcer方式监听屏障删除事件
Stat stat = client.checkExists().usingWatcher(new Watcher() {@Overridepublic void process(WatchedEvent event) {if (event.getType() == Event.EventType.NodeDeleted) {System.out.println("节点删除");//节点删除 通知主线程synchronized (obj){obj.notifyAll();}}}
}).forPath(path);
//主线程同步等待屏障删除
synchronized (obj){obj.wait();
}System.out.println("barrier delete");

这里最后主线程会等待另一个线程执行完成才继续。这里在同一个程序里模拟,同时运行两个程序可能更直观。

另外Curator的recipes也提供的对barrier的封装:DistributedBarrier类。

使用例子:

CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new RetryOneTime(1));
try {client.start();final DistributedBarrier barrier = new DistributedBarrier(client, "/barrier");//添加屏障barrier.setBarrier();new Thread(()->{try {Thread.sleep(2000);//屏障移除barrier.removeBarrier();}catch (Exception e) {e.printStackTrace();}}).start();//阻塞等待屏障移除barrier.waitOnBarrier(10, TimeUnit.SECONDS);System.out.println("end");
} catch (Exception e) {e.printStackTrace();
} finally {client.close();
}

其内部阻塞原理还是使用的基础的wait,notify机制。这里封装方法可以设置等待时间。

Double Barriers

double barriers即多屏障。在某些情况下需要多个条件同时满足程序才可以继续。比如批量任务,并行分成5个线程任务去做同一阶段工作。5个线程都执行完成才可进入下一阶段。

还是使用Curator封装的DistributedDoubleBarrier来演示:

CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new RetryOneTime(1));
client.start();
ExecutorService executor = Executors.newFixedThreadPool(5);
int quantity = 5;//屏障数量
String barrierPath = "/barrier1";//屏障节点路径
for (int i = 0; i < 5; i++) {executor.execute(()->{DistributedDoubleBarrier barrier = new DistributedDoubleBarrier(client,barrierPath,quantity);try {int time = 1000*new Random().nextInt(10);System.out.println(time+ " sleeps for enter,"+Thread.currentThread().getName());Thread.sleep(time);/**当前参与者执行完前置逻辑进入屏障等待其它参与者到达(阻塞等待)当所有参与者都到达屏障点后,屏障会通知所有参与者继续执行(解除阻塞)*/barrier.enter(10,TimeUnit.SECONDS);System.out.println(System.currentTimeMillis()+ " do sth,"+Thread.currentThread().getName());time = 1000*new Random().nextInt(10);System.out.println(time+ " sleeps for leave,"+Thread.currentThread().getName());Thread.sleep(time);/**完成同步操作后,调用leave()方法告知屏障该参与者已经离开屏障点,并等待其他参与者也离开当所有参与者都离开屏障点后,屏障会通知所有参与者继续执行后续操作*/barrier.leave();//删除屏障System.out.println(System.currentTimeMillis()+" leave,"+Thread.currentThread().getName());} catch (Exception e) {e.printStackTrace();}});
}executor.shutdown();

这里定义了5个屏障,所有的程序会在barrier.enter()处阻塞等待,直到所有的线程都执行到该方法才会继续执行。这时候查看/barrier1节点,会发现其下有5个uuid类型的子节点和一个ready节点。每个enter的线程创建了一个子节点,barrier判断达到屏障数量时自动创建一个ready节点。

[zk: localhost:2181(CONNECTED) 20] ls /barrier1
[0ffbe0f0-0bf6-4098-a494-912ce57d8f5f, 10e54092-9909-4a0a-a764-774e55584b1d, 4b72c6bb-bff4-4bf4-9762-dbb56daaaf87, 8d8ecafa-31a8-4799-8b49-35f61098a05f, cbe75b72-8fdb-48dd-9620-2d34b59d411e, ready]

后面leave()方法离开屏障点又是一个阻塞点,屏障会等到所有的参与者都调用leave方法后才会通知所有参与者继续执行。最后 enter()->leave()方法之间是多个参与者同步操作业务逻辑。


http://www.ppmy.cn/news/1213651.html

相关文章

2022年03月 Python(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 下面有关random的常用方法,描述错误的是? A: random.random()生成一个[0.0,1.0)之间的随机小数 B: random.randint(a,b)生成一个[a,b]之间的随机整数 C: random.choice(seq)从序列中…

CSS BFC是什么,应用实例

CSS BFC&#xff08;块级格式化上下文&#xff09;是一个Web页面渲染时生成的一种独立的渲染区域&#xff0c;它定义了一套渲染规则&#xff0c;用于控制块级盒子的布局和浮动元素与其他元素的交互。BFC可以避免出现一些常见的布局问题&#xff0c;提高页面的可靠性和可维护性。…

解决VSCode中文乱码问题

解决VSCode乱码问题 1.问题描述&#xff1a;2.原因分析&#xff1a;3.解决方案&#xff1a;1&#xff09;解决步骤2&#xff09;深入分析 4.总结 1.问题描述&#xff1a; 最近用vscode的时候突然发现中文字符出现乱码。在网上找了好几种方法都不行&#xff0c;用各种编码格式打…

FlinkSQL聚合函数(Aggregate Function)详解

使用场景&#xff1a; 聚合函数即 UDAF&#xff0c;常⽤于进多条数据&#xff0c;出⼀条数据的场景。 上图展示了⼀个 聚合函数的例⼦ 以及 聚合函数包含的重要⽅法。 案例场景&#xff1a; 关于饮料的表&#xff0c;有三个字段&#xff0c;分别是 id、name、price&#xff0…

保姆级jupyter lab配置清单

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

sass 封装媒体查询工具

背景 以往写媒体查询可能是这样的&#xff1a; .header {display: flex;width: 100%; }media (width > 320px) and (width < 480px) {.header {height: 50px;} }media (width > 480px) and (width < 768px) {.header {height: 60px;} }media (width > 768px) …

第一百七十回 Material3中的IconButton

文章目录 1. 概念介绍2. 使用方法2.1 filled风格2.2 filledTonal风格2.3 outlined风格 3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"如何修改NavigationBar组件的形状"相关的内容&#xff0c;本章回中将 介绍IconButtion组件.闲话休…

​软考-高级-系统架构设计师教程(清华第2版)【第3章 信息系统基础知识(p120~159)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第3章 信息系统基础知识(p120~159)-思维导图】 课本里章节里所有蓝色字体的思维导图