Redis08-分布式锁
分布式锁的核心是实现多进程之间互斥,而满足这一点的方式有很多,常见的有三种:
MySQL | Redis | Zookeeper | |
---|---|---|---|
互斥 | 利用mysql本身的互斥锁机制 | 利用setnx这样的互斥命令 | 利用节点的唯一性和有序性实现互斥 |
高可用 | 好 | 好 | 好 |
高性能 | 一般 | 好 | 一般 |
安全性 | 断开连接,自动释放锁 | 利用锁超时时间,到期释放 | 临时节点,断开连接自动释放 |
注意redis的超时释放
解决方法:释放锁的时候判断一下锁标识
==使用Redis事务(Redis只保证了原子性,不能保证一致性,要不然再加上乐观锁进行判断,复杂==
==使用简单的Lua脚本,在一个脚本中编写多条Redis命令,确保多条命令执行时的原子性。==
样例:
-- 比较标识的一致性 |
基于Redis的分布式锁实现思路:
- 利用set nx ex获取锁,并设置过期时间,保存线程标示
- 释放锁时先判断线程标示是否与自己一致,一致则删除锁
特性:
- 利用set nx满足互斥性
- 利用set ex保证故障时锁依然能释放,避免死锁,提高安全性·利用Redis集群保证高可用和高并发特性
Redsson可重入锁
==基于setnx存在以下问题==
不可重入:同一个线程无法多次获取同一把锁
不可重试:获取锁只尝试一次就返回false,没有重试机制
锁超时释放虽然可以避免死锁,但如果是业务执行耗时较长,也会导致锁释放,存在安全隐患
如果Redis提供了主从集群,主从同步存在延迟,当主宕机时,如果从并同步主中的锁数据,则会出现锁实现
可重入原理
Redisson分布式锁原理:
- 可重入:利用hash结构记录线程id和重入次数
- 可重试:利用信号量和PubSub功能实现等待、唤醒,获取锁失败的重试机制
- 超时续约:利用watchDog,每隔一段时间( releaseTime / 3),重置超时时间
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 玖!
评论