使用
使用set key value ex 5 nx
命令设置key value 5秒过期 不存在才能设置成功,成功代表获取了分布式锁
随机值
在set时,key为固定,但value对不同线程应不同,如使用线程名。
如果使用的value相同会有什么问题?我们假设固定为key=lock_key,value=lock_value
假设线程1获取到了分布式锁,超时30秒,但线程1的实际执行实际达到了40秒,在第30秒的时候锁被自动释放,线程2拿到了锁,线程2在继续自己的任务,假设是30秒。十秒后线程1结束,释放了锁,但这时候释放的是线程2设置的锁,从而导致同步出错。
若每个线程对应的value是不同的,在释放锁时只有value相同才会释放。但这个判断删除操作不是原子性的,可以使用lua脚本方式实现
if redis.call('get', KEYS[1]) == ARGV[1]
then return redis.call('del', KEYS[1])
else return 0 end
锁超时
如上面所说的,如果获取锁设置了30秒超时,但实际任务执行时间超过了30秒怎么办?
可以使用守护线程的方式,在第29秒时给key续命10秒,然后十秒后守护线程继续执行。
主线程执行结束守护线程也会跟随销毁
单机故障引发并发问题
对于主从同步的情况,在主节点拿到了锁,但这个锁没有同步给从节点的时候主节点挂了,从节点上位,从而其他线程也能拿到锁,导致两个客户端拿到了锁。这种情况如果业务不能容忍可以考虑官方提供的RedLock
参考
https://blog.csdn.net/u010325193/article/details/87887030
https://www.cnblogs.com/gxyandwmm/p/9588383.html
来源:CSDN
作者:Mutou_ren
链接:https://blog.csdn.net/Mutou_ren/article/details/103846223