首页 / 深度学习 / Java - 深度学习 - 分布式锁
Java - 深度学习 - 分布式锁
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java - 深度学习 - 分布式锁,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3384字,纯文字阅读大概需要5分钟。
内容图文
![Java - 深度学习 - 分布式锁](/upload/InfoBanner/zyjiaocheng/644/f5ed175e97604ed9b4691a03f37495f6.jpg)
前言
整理了一下自己日常中使用到的一些分布式锁功能,特别说明,因为还在整理知识点,有些东西我直接使用之前写的PythonDemo一笔盖过,望体谅,最近有点忙。
分布式锁
分布式锁是通过互诉等手段,来实现分布式系统之间同步访问共享资源,以保证数据的一致性。
一般实现分布式锁都有哪种方式
方法 | 优势 | 劣势 | 备注 |
---|---|---|---|
Redis | 性能高 | 可靠性低,争议多 | 不推荐,但业务不需要太严谨时可以考虑 |
ZooKeeper | 性能一般 | 可靠性高 | 推荐,但性能未必出色 |
锁冲突情况
-
Redis:如果没有获取到这把锁,只能自己每个一秒尝试一下,看能否拿到这把锁,开销大
-
ZooKeeper:如果没有获取到这把锁,对这个锁注册监听器,被释放时通知节点挂掉的情况,开销小
异常情况
- Redis非redis-cluster模式下,如单节点,哨兵Sentinel,节点挂掉后,需要通过过期时间自动释放
- zk的话,因为创建的是临时znode,只要客户端挂了,znode就没了,此时就自动释放锁
Redis分布锁
官方叫做RedLock算法,是redis官方支持的分布式锁算法。
Redis 2.8 版本中作者加入了 set 指令的扩展参数,使得 setnx 和 expire 指令可以一起执行
三个重要的考量点
- 互斥(只能有一个客户端获取锁)
- 不能死锁
- 容错(大部分redis节点或者这个锁就可以加可以释放)
为什么key要用随机值?
因为如果某个客户端获取到了锁,但是阻塞了很长时间才执行完,此时可能已经自动释放锁了,此时可能别的客户端已经获取到了这个锁,要是你这个时候直接删除key的话会有问题,所以得用随机值加上面的lua脚本来释放锁。
最普通的实现方式,如果就是在redis里创建一个key算加锁
参数 | 说明 |
---|---|
nx | 只有key不存在的时候才能设置成功 |
px | 多少秒后自动释放 |
set mykey 随机值 nx px 5
释放锁就是删除key,但是一般可以用lua脚本删除,判断value一样才删除
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
风险
- 如果是普通的redis单实例,那就是单点故障。
- 比如在 Sentinel 集群中,主节点挂掉时,从节点会取而代之,客户端上却并没有明显感知。从节点还没来得及同步过来,主节点就挂掉了,这样就会导致系统中同样一把锁被两个客户端同时持有,不安全性由此产生。
使用RedLock算法
针对以上问题,可以使用redis cluster,假设有5个redis master实例。然后执行如下步骤获取一把锁:
1)获取当前时间戳,单位是毫秒
2)跟上面类似,轮流尝试在每个master节点上创建锁,过期时间较短,一般就几十毫秒
3)尝试在大多数节点上建立一个锁,比如5个节点就要求是3个节点(n / 2 +1)
4)客户端计算建立好锁的时间,如果建立锁的时间小于超时时间,就算建立成功了
5)要是锁建立失败了,那么就依次删除这个锁
6)只要别人建立了一把分布式锁,你就得不断轮询去尝试获取锁
讨论
其实在正常工作中,我们不太推荐这个锁,而且这个官方发布的RedLock算法有很多争议,国外不乏大牛质疑这个做法,我找到了两篇文章,我觉得写的很好
部署
ZooKeeper实现分布式锁
**锁定义:**Zookeeper通过创建临时数据节点来表示一个锁,并且是顺序节点
**获取锁:**成功创建数据节点的客户端即为获取锁。未获取锁的客户端通过监听该节点变更情况,以便重新获取锁
释放锁:
- 当前客户端发生宕机的情况下,临时节点自动删除
- 正常业务逻辑处理完毕后,客户端自动删除自己创建的临时节点
简单示例
以下代码只是简单实现,基于zookeeper的临时顺序节点去实现的,不建议这个,下面有高级用法
Curator - 实现分布式锁
它的实现也是通过创建临时的顺序节点机制
类型 | 说明 |
---|---|
InterProcessMutex | 互斥锁 |
zk客户端登录,创建节点
create /orderNo 1000
代码实现,轻松实现分布式锁
// 获得锁
interProcessMutex.acquire();
// 生成订单
int order = generateOrder(orderNoPath, curatorFramework);
System.out.println("当前订单号:" + order);
// 释放
interProcessMutex.release();
完整代码
Java Zookeeper - Curator的使用
内容总结
以上是互联网集市为您收集整理的Java - 深度学习 - 分布式锁全部内容,希望文章能够帮你解决Java - 深度学习 - 分布式锁所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。