Redis-setnx实现分布式锁
Redis实现分布式锁主要利用Redis的setnx命令。setnx是SET if not exists(如果不存在,则SET)的简写。(NX是互斥、EX是设置超时时间)
但是如上会面临一个问题,当业务执行时间太长,导致业务还没执行完锁已到期,这样的话当其它线程进来时就不能保证业务的原子性。
Redisson实现分布式锁
Redisson中就解决了Redis中的业务执行太长导致提前锁释放的问题和锁不可重入问题
在redisson中需要手动加锁,并且可以控制锁的失效时间和等待时间,当锁住的一个业务还没有执行完成的时候,在redisson中引入了一个看门狗机制,就是说每隔一段时间就检查当前业务是否还持有锁,如果持有就刷新加锁的持有时间,当业务执行完成之后需要使用释放锁就可以了
releaseTime:锁的过期时间,默认30秒
Redisson实现分布式锁-可重入
主要是根据线程id来判断,这个重入其实在内部就是判断是否是当前线程持有的锁,如果是当前线程持有的锁就会计数,如果释放锁就会在计算上减一。在存储数据的时候采用的hash结构,大 key可以按照自己的业务进行定制,其中小key是当前线程的唯一标识,value 是当前线程重入的次数,这样做是为了避免死锁的产生。
如上在只能在单机Redis中使用,当出现Redis集群时,setnx就没有意义了
Redisson实现分布式锁-主从一致性
RedLock(红锁):不能只在一个redis实例上创建锁,应该是在多个redis实例上创建锁(Redis实例数量/ 2+1),避免在一个redis实例上加锁
但官方不建议使用,因为红锁实现复杂,性能差,运维繁琐
如果项目中使用的Redis集群,redis本身就是支持高可用的,做到强一致性,就非常影响性能,所以如果有强一致性要求高的业务,建议使用zookeeper实现的分布式锁,它是可以保证强一致性的。
总结