Redis分布式锁篇
用jdk中的锁保证数据的安全性,那么此时就需要使用分布式锁。
作用:可以保证在分布式系统中多个线程访问共享数据时数据的安全性
1、在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行
2、高可用的获取锁与释放锁
3、高性能的获取锁与释放锁
4、具备可重入特性
5、具备锁失效机制,防止死锁
可重入特性:获取到锁的线程再次调用需要锁的方法的时候,不需要再次获取锁对象。
注意:锁具备可重入性的主要目的是为了防止死锁。
1、数据库
2、zookeeper
3、redis
20、Redis怎么实现分布式锁思路?(高频)
127.0.0.1:6379> setnx lock value1 #在键lock不存在的情况下,将键key的值设置为value1
(integer) 1
127.0.0.1:6379> setnx lock value2 #试图覆盖lock的值,返回0表示失败
(integer) 0
127.0.0.1:6379> get lock #获取lock的值,验证没有被覆盖
"value1"
127.0.0.1:6379> del lock #删除lock的值,删除成功
(integer) 1
127.0.0.1:6379> setnx lock value2 #再使用setnx命令设置,返回0表示成功
(integer) 1
127.0.0.1:6379> get lock #获取lock的值,验证设置成功
"value2"
上面这几个命令就是最基本的用来完成分布式锁的命令。
加锁:使用setnx key value命令,如果key不存在,设置value(加锁成功)。如果已经存在lock(也就是有客户端持有锁了),则设置失败(加锁失败)。
解锁:使用del命令,通过删除键值释放锁。释放锁之后,其他客户端可以通过setnx命令进行加锁。
然后加锁的代码就会变成这样。
// 加锁的代码
// requestId描述请求的唯一性,哪一个线程加锁了在解锁的时候就需要使用哪一个线程
public static boolean tryLock(Jedis jedis , String key, String requestId , int expireTime) {
SetParams setParams = new SetParams();
setParams.nx() ;
setParams.ex(expireTime) ;
return "OK".equalsIgnoreCase(jedis.set(key , requestId , setParams)); // 不存则保存成功返回的是OK
}
22、Redis实现分布式锁如何合理的控制锁的有效时长?(高频)
1、程序员自己去把握,预估一下业务代码需要执行的时间,然后设置有效期时间比执行时间长一些,保证不会因为自动解锁影响到客户端业务代码的执行。
2、给锁续期。
锁续期实现思路:当加锁成功后,同时开启守护线程,默认有效期是用户所设置的,然后每隔10秒就会给锁续期到用户所设置的有效期,只要持有锁的客
户端没有宕机,就能保证一直持有锁,直到业务代码执行完毕由客户端自己解锁,如果宕机了自然就在有效期失效后自动解锁。
上述的第二种解决方案可以使用redis官方所提供的Redisson进行实现。
中进行锁续期的这种机制被称为"看门狗"机制。
redission支持4种连接redis方式,分别为单机、主从、Sentinel、Cluster 集群。
解决方案:
1、使用Redis的哨兵模式构建一个主从架构的Redis集群
2、使用Redis Cluster集群
RedLock的方案基于2个前提:
1、不再需要部署从库和哨兵实例,只部署主库
2、但主库要部署多个,官方推荐至少5个实例
也就是说,想使用RedLock,你至少要部署5个Redis实例,而且都是主库,它们之间没有任何关系,都是一个个孤立的实例。
1、客户端先获取【当前时间戳T1】
2、客户端依次向这个5个Redis实例发起加锁请求,且每个请求会设置超时时间(毫秒级,要远小于锁的有效时间),如果某一个实例加锁失败(包括网络超
时,锁被其他的人持有等各种异常情况),就立即向下一个Redis实例申请加锁
3、如果客户端从 >=3 个(大多数)以上Redis实例加锁成功,则再次获取【当前时间戳T2】, 如果 T2 - T1 < 锁的过期时间,此时,认为客户端加锁成功,
否则加锁失败
4、加锁成功,去操作共享资源
5、加锁失败,向【全部节点】发起释放锁请求
总结4个重点:
1、客户端在多个Redis实例上申请加锁
2、必须保证大多数节点加锁成功
3、大多数节点加锁的总耗时,要小于锁设置的过期时间
4、锁释放,要向全部节点发起释放锁请求
24.1 为什么要在多个实例上加锁?
本质上是为了【容错】, 部分实例异常宕机,剩余的实例加锁成功,整个锁服务依旧可用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)