redis学习笔记(九) 分布式锁

2019-09-25  本文已影响0人  云师兄

1. 引子

在多线程环境下,如果想对共享内存中的数据进行互斥访问且想保证线程安全,Java可以使用很多种锁来实现;但是在分布式环境下,由于线程不在一个进程中,使用Java中提供的锁就没有用了,一般会使用redis的setnx来实现分布式锁。

2. 加锁的正确姿势

使用setnx加锁需要满足下面三个正确姿势:

3. 解锁的正确姿势

同样的,解锁分为三步:

  1. 从redis获取数据。
  2. 判断value是否和本地保存的value一致(是不是自己上的锁)
  3. 删除该键值对

这三步也要求保证原子性,不然在高并发环境下会有问题。一般要保证原子性,可以在redis使用lua脚步来实现:

if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

4. 注意

Redis的setnx命令本身不带expire参数以设置过期时间,因此只能先setnx获取锁后,再给这个key设置过期时间。但是由于这是两步操作,可能会导致刚执行完setnx后,redis就挂了,这种请求就会导致这个锁永远不能释放。为解决该问题,redis 2.6的版本后,支持set命令可以同时支持nx和过期时间两个操作:

屏幕快照 2019-06-23 下午7.19.36.png

所以使用上述set命令才能万无一失的实现分布式锁。

上一篇下一篇

猜你喜欢

热点阅读