分布式锁
利用setnx, key若存在, 则创建失败的特性
1 | setnx lock true |
问题1: 死锁
若在del之前出现问题, 则该锁永远无法释放, 产生死锁
解决:
给该key加上超时时间; 则从锁层面来说, 超时自动释放
1 | setnx lock true |
问题2: 原子性问题
若setnx与expire之间挂掉了怎么办?
解决:
redis 2.8 版本之前: 开源社区的分布式锁library
redis 2.8 版本:
1 | set lock true ex 5 nx |
问题3: 超时问题
线程1获得锁后超时, 锁释放, 线程2持有锁. 但此时线程1未执行完的逻辑还是可以执行的, 线程1继续执行, 将线程2持有的锁del掉.
解决
给锁赋值一个随机数, 锁释放前先看随机数是否匹配 (以此来验证是不是同一个线程释放的锁)
1 | tag = random() |
但是, redis.delifequals(key, tag) 中匹配value和删除key不是一个原子操作, 有可能存在get到value后, 值发生改变, 然后错误的del. 这里可以使用lua脚本来处理