博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis分布式锁
阅读量:4560 次
发布时间:2019-06-08

本文共 1496 字,大约阅读时间需要 4 分钟。

理解分布式锁

在分布式环境下保证不同节点的线程同步执行
简单来说就是多进程对共享资源的同步访问
在单进程中使用synchronize或者lock等方式就可实现同步,这是在一个jvm上的资源同步,而要做到多进程多jvm的资源同步,就要通过分布式锁

条件

1.在任意时刻只有一个客户端可以拥有锁

2.不能发生死锁--就算客户端在拥有锁的时候崩溃,不会导致其他等待的客户端一直拿不到锁

3.加锁与解锁都只能由同一个客户端完成

实现分布式锁几种方法

1.Memcached分布式锁
利用Memcached的add命令。此命令是原子性操作,只有在key不存在的情况下,才能add成功,也就意味着线程得到了锁。
2.Redis分布式锁
和Memcached的方式类似,利用Redis的setnx命令。此命令同样是原子性操作,只有在key不存在的情况下,才能set成功。(setnx命令并不完善,后续会介绍替代方案)
3.Zookeeper分布式锁
利用Zookeeper的顺序临时节点,来实现分布式锁和等待队列。Zookeeper设计的初衷,就是为了实现分布式锁服务的。
4.Chubby
Google公司实现的粗粒度分布式锁服务,底层利用了Paxos一致性算法。
 
作者:程序员小灰链接:https://juejin.im/post/5b16148a518825136137c8db来源:掘金

 

redis分布式锁

1.加锁

String result = jedis.set(Key, requestID, "nx", "px", expireTime);
参数解释
  1. key为锁的名称,传自己设定的唯一值key
  2. requestID传本线程名称,用于解锁时确认是否是本线程的锁
  3. "nx"表明只有key不存在时才执行set value,成功返回1,不成功会返回0
  4. "px"表明为key设置过期时间
  5. exprieTime传过期时间
参数意义
(1)key是每个进程执行set的key,是唯一值,也是锁的名称
(2)requestID保证自己解锁时解的是自己的锁
        有一种情况是有一进程A执行较慢导致过期时间到了而还没执行解锁,此时锁就会因为到过期时间自动解除,另一进程B获得锁,然后A完成任务执行解锁,那么A就解了B的锁
        辅助方法是为获得锁的该线程建立一个守护线程,不断给锁增加时间,防止锁过时
(3)"nx"与lockkey共同实现锁,每个进程要获得锁就执行set,只有返回1才能拥有锁,返回0没有锁需等待
(4)"px"与expireTime配合为key设置过期时间后,就算客户端崩溃不能执行解锁,锁也会自动解除

2.解锁

String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
使用lua脚本执行解锁--因为判断锁与释放锁不是原子性的,使用lua脚本实现原子性

3.示意图

(一)AB执行set获取锁,其中A获得了锁 
(二)A执行代码
(三)A执行完代码后先判断是否是自己的锁,确认后再释放
(四)B获得锁
 
 
 
 
 

转载于:https://www.cnblogs.com/ming-szu/p/9454873.html

你可能感兴趣的文章
GUC-1 volatile
查看>>
用 Vue 全家桶二次开发 V2EX 社区
查看>>
用css实现自定义虚线边框
查看>>
图像矫正-基于opencv实现
查看>>
Python冒泡排序
查看>>
NGUI 滑动与点击事件冲突处理
查看>>
toLua踩坑
查看>>
php手册总结《安装与配置》
查看>>
获取手机CCID号
查看>>
PAT-乙级-1001. 害死人不偿命的(3n+1)猜想 (15)
查看>>
自定义IP协议
查看>>
8、sort排序中比较函数的几种应用方式
查看>>
Apache 解析.htaccess
查看>>
Sublime Text 2学习记录
查看>>
UWP开发入门(三)——{x:Bind}扩展标记
查看>>
SoupUI接口测试学习分享
查看>>
HDU2275
查看>>
tomcat:A docBase * inside the host appBase has been specifi, and will be ignored
查看>>
动态创建按钮及处理OnClick事件
查看>>
字符集
查看>>