redis学习:分布式锁
分布式锁本质是占茅坑 当别人也想上厕所 但发现坑位已经被占了 只能等你拉好
redis一般使用setnx来占坑 del去释放 。但如果在del之前 执行的逻辑出错了 可能导致del无法被调用 产生死锁。为了应对这样的问题 一般会设置个expire过期时间 就算del没被调用 在一定时间后也会释放锁。但setnx expire这个不是原子性的 如果在expire之前出故障线程挂了 那么也会有死锁 且expire要依赖setnx来执行 所以也不能使用事务来执行 但幸好redis已经把这个问题解决了 set ex nx就是一条原子指令 把setnx和expire结合在一起
超时问题:分布式锁解决不了超时问题 当一个业务执行时间太长 以至于超过expire过期时间 那么就可能产生问题。如线程1执行时间过长 导致锁提前释放 那么线程2就会获得锁并开始执行 如果此时线程1完成 并执行del 那么又会把锁释放 让线程3也开始获得锁并执行 这可能会带来一些问题。为了解决线程1在锁过期之后又del锁 可以设置随机变量 set key random(随机产生的数字) 每次在要del的时候检查一下这个key的值与这个线程产生的随机数是否匹配 整个检查加删除使用lua脚本来实现 以确保原子性 若不使用 则在检查完之后 正好过期 其他客户端抢占锁 此时又会把别人的锁给删了。