查看“Zookeeper:分布式锁”的源代码
←
Zookeeper:分布式锁
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:Zookeeper]] == 关于 == 分布式锁是控制分布式系统之间同步访问共享资源的一种方式。 下面介绍 zookeeper 如何实现分布式锁,讲解'''排他锁'''和'''共享锁'''两类分布式锁。 == 排他锁 == '''排他锁'''(Exclusive Locks),又被称为'''写锁'''或'''独占锁'''。 : 如果事务 T1 对数据对象 O1 加上排他锁,那么整个加锁期间,只允许事务 T1 对 O1 进行读取和更新操作,其他任何事务都不能进行读或写。 定义锁: '''<syntaxhighlight lang="java" highlight=""> /exclusive_lock/lock </syntaxhighlight>''' 实现方式:利用 zookeeper 的'''同级节点的唯一性'''特性: # 在需要获取排他锁时,所有的客户端试图通过调用 “create()” 方法,在 /exclusive_lock 节点下创建'''临时子节点''' /exclusive_lock/lock,最终只有一个客户端能创建成功,那么此客户端就获得了分布式锁。 # 同时,所有没有获取到锁的客户端可以在 /exclusive_lock 节点上注册一个子节点变更的 '''watcher''' 监听事件,以便重新争取获得锁。 == 共享锁 == '''共享锁'''(Shared Locks),又称'''读锁'''。 : 如果事务 T1 对数据对象 O1 加上了共享锁,那么当前事务只能对 O1 进行读取操作,其他事务也只能对这个数据对象加共享锁,直到该数据对象上的所有共享锁都释放。 定义锁: '''<syntaxhighlight lang="java" highlight=""> /shared_lock/[hostname]-请求类型W/R-序号 </syntaxhighlight>''' 实现方式: # 客户端调用 “create” 方法创建类似定义锁方式的'''临时顺序节点'''。 # 客户端调用 “getChildren” 接口来获取所有已创建的子节点列表。 # 判断是否获得锁: #* 读请求:如果所有比自己小的子节点都是读请求或者没有比自己序号小的子节点,表明已经成功获取共享锁,同时开始执行度逻辑; #* 写请求:如果自己不是序号最小的子节点,那么就进入等待。 # 如果没有获取到共享锁: #* 读请求:向比自己序号小的'''最后一个写请求节点'''注册 '''watcher''' 监听; #* 写请求:向比自己序号小的'''最后一个节点'''注册 '''watcher''' 监听。 == curator 实现分布式锁 == 实际开发过程中,可以 curator 工具包封装的API('''curator-recipes''')帮助我们实现分布式锁。 <syntaxhighlight lang="java" highlight=""> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>x.x.x</version> </dependency> </syntaxhighlight> === curator 的几种锁方案 === curator 的几种锁方案: # '''InterProcessMutex''':分布式可重入排它锁 # '''InterProcessSemaphoreMutex''':分布式排它锁 # '''InterProcessReadWriteLock''':分布式读写锁 === 示例 === 下面例子模拟 50 个线程使用重入排它锁 InterProcessMutex 同时争抢锁: : <syntaxhighlight lang="java" highlight=""> public class InterprocessLock { private static CuratorFramework getZkClient() { String zkServerAddress = "192.168.3.39:2181"; ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3, 5000); CuratorFramework zkClient = CuratorFrameworkFactory.builder() .connectString(zkServerAddress) .sessionTimeoutMs(5000) .connectionTimeoutMs(5000) .retryPolicy(retryPolicy) .build(); zkClient.start(); return zkClient; } public static void main(String[] args) { CuratorFramework zkClient = getZkClient(); String lockPath = "/lock"; InterProcessMutex lock = new InterProcessMutex(zkClient, lockPath); //模拟50个线程抢锁 for (int i = 0; i < 50; i++) { new Thread(new TestThread(i, lock)).start(); } } static class TestThread implements Runnable { private Integer threadFlag; private InterProcessMutex lock; public TestThread(Integer threadFlag, InterProcessMutex lock) { this.threadFlag = threadFlag; this.lock = lock; } @Override public void run() { try { lock.acquire(); System.out.println("第"+threadFlag+"线程获取到了锁"); //等到1秒后释放锁 Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); }finally { try { lock.release(); } catch (Exception e) { e.printStackTrace(); } } } } } </syntaxhighlight> : 控制台每间隔一秒钟输出一条记录: : [[File:Zookeeper:分布式锁:curator:InterProcessMutex示例.png|600px]]
返回至“
Zookeeper:分布式锁
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息