Redis 分布式锁的正确实现原理演化历程与 Redisson 实战总结

作者:微信小助手

发布时间:2021-11-29T08:47:45

可能是最完善的 Redis 分布式锁原理与实战总结,建议收藏,文末送书福利

Redis 分布式锁使用 SET 指令就可以实现了么?在分布式领域 CAP 理论一直存在。

分布式锁的门道可没那么简单,我们在网上看到的分布式锁方案可能是有问题的。

「码哥」一步步带你深入分布式锁是如何一步步完善,在高并发生产环境中如何正确使用分布式锁。

在进入正文之前,我们先带着问题去思考:

  • 什么时候需要分布式锁?
  • 加、解锁的代码位置有讲究么?
  • 如何避免出现锁再也无法删除?
  • 超时时间设置多少合适呢?
  • 如何避免锁被其他线程释放
  • 如何实现重入锁?
  • 主从架构会带来什么安全问题?
  • 什么是 Redlock
  • Redisson 分布式锁最佳实战
  • 看门狗实现原理
  • ……

什么时候用分布式锁?

码哥,说个通俗的例子讲解下什么时候需要分布式锁呢?

诊所只有一个医生,很多患者前来就诊。

医生在同一时刻只能给一个患者提供就诊服务。

如果不是这样的话,就会出现医生在就诊肾亏的「肖菜鸡」准备开药时候患者切换成了脚臭的「谢霸哥」,这时候药就被谢霸哥取走了。

治肾亏的药被有脚臭的拿去了。

当并发去读写一个【共享资源】的时候,我们为了保证数据的正确,需要控制同一时刻只有一个线程访问。

分布式锁就是用来控制同一时刻,只有一个 JVM 进程中的一个线程可以访问被保护的资源。

分布式锁入门

65 哥:分布式锁应该满足哪些特性?

  1. 互斥:在任何给定时刻,只有一个客户端可以持有锁;
  2. 无死锁:任何时刻都有可能获得锁,即使获取锁的客户端崩溃;
  3. 容错:只要大多数 Redis的节点都已经启动,客户端就可以获取和释放锁。

码哥,我可以使用 SETNX key value 命令是实现「互斥」特性。

这个命令来自于SET if Not eXists的缩写,意思是:如果 key 不存在,则设置 value 给这个key,否则啥都不做。Redis 官方地址说的:

命令的返回值:

  • 1:设置成功;
  • 0:key 没有设置成功。

如下场景:

敲代码一天累了,想去放松按摩下肩颈。

168 号技师最抢手,大家喜欢点,所以并发量大,需要分布式锁控制。

同一时刻只允许一个「客户」预约 168 技师。

肖菜鸡申请 168 技师成功:

> SETNX lock:168 1
(integer) 1 # 获取 168 技师成功

谢霸哥后面到,申请失败:

> SETNX lock 2
(integer) 0 # 客户谢霸哥 2 获取失败

此刻,申请成功的客户就可以享受 168 技师的肩颈放松服务「共享资源」。

享受结束后,要及时释放锁,给后来者享受 168 技师的服务机会。

肖菜鸡,码哥考考你如何释放锁呢?

很简单,使用 DEL 删除这个 key 就行。