实现原理
通过set ex nx命令和lua脚本实现。
加锁:set lock_key uniqueValue ex expire_time nx
解锁的lua脚本,通过value判断锁是不是自己加的,是则删除
if redis.call("GET",KEYS[1]) == ARGV[1]
then
return redis.call("DEL",KEYS[1])
else
return 0
end
常见问题
业务未执行完,锁已经过期
可以设置一种续约机制(redisson的看门狗机制),线程A在执行的时候,启动一个守护线程,每隔一段时间检测线程A是否执行完成,如果没有执行完,但是快过期了,就重新设置超时时间。
单点故障问题
加机器,变集群
主从问题
主节点宕机,锁还没同步到从节点,然后从节点变成主节点,但是由于没锁,会使其他应用同时获取锁。
使用red lock解决
red lock是什么?
red lock是一种分布式锁的实现方法,主要是解决当部分节点发生异常时,不会影响锁的使用和数据访问。
使用red lock需要部署集群,官方推荐至少5个,不需要部署从库和哨兵,仅需主库,由于没有主从,所有没有同步丢失锁的问题。
这几个实例之间没有任何关系,也没有信息交互,客户端会对这几个实例依次申请锁,如果申请超过半数,则表示申请成功。加锁成功执行业务逻辑,失败则依次向所有节点释放锁。
网络问题
可能会与Redis断开连接,如果锁未设置过期时间,会导致锁无法正常释放,锁过多的话,还可能导致死锁
时钟漂移
过期时间的判断依赖实例的时间,如果实例的时间出现漂移,可能会导致锁直接失效。
通过NTP服务,统一各节点时间。
