0%

redis---分布式锁

分布式锁

利用setnx, key若存在, 则创建失败的特性

1
2
setnx lock true
del lock

问题1: 死锁

若在del之前出现问题, 则该锁永远无法释放, 产生死锁

解决:

给该key加上超时时间; 则从锁层面来说, 超时自动释放

1
2
3
setnx lock true
expire lock 5
del lock

问题2: 原子性问题

若setnx与expire之间挂掉了怎么办?

解决:

redis 2.8 版本之前: 开源社区的分布式锁library
redis 2.8 版本:

1
2
set lock true ex 5 nx
del lock

问题3: 超时问题

线程1获得锁后超时, 锁释放, 线程2持有锁. 但此时线程1未执行完的逻辑还是可以执行的, 线程1继续执行, 将线程2持有的锁del掉.

解决

给锁赋值一个随机数, 锁释放前先看随机数是否匹配 (以此来验证是不是同一个线程释放的锁)

1
2
3
4
tag = random()
if redis.set("lock", tag, nx=true, ex=5):
do somthing...
redis.delifequals(key, tag)

但是, redis.delifequals(key, tag) 中匹配value和删除key不是一个原子操作, 有可能存在get到value后, 值发生改变, 然后错误的del. 这里可以使用lua脚本来处理