【图文并茂】大白话快速讲懂 Redis 分布式锁

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料: 

ba6148ce890e635cf08458763db58d75.gif

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

来源:juejin.cn/post/
7255902957035323450


技术的演变都是为了解决问题的,这也是技术演变吸引人的一点。

Redis分布式锁

分布式锁顾名思义 就是在分布式场景下 多台机器竞争一项资源去加锁

最简单的版本

首先就是最简单的版本,可以通过Redis的setnx命令(set if not exist)

setnx key value

这个命令会使Redis中如果不存在key就会创建值为value的key,存在的话就返回0

d6e57db9f267215251c6df67e02844d2.jpeg

过期时间

如果获取锁的机器服务挂了呢?

47de6fa936b6c920cd7091399ed60eb4.jpeg

其他机器:奶奶滴 怎么还不释放锁?

所以 有个兜底策略:设置过期时间(挂了之后过段时间锁自动过期释放了)

此时可以用一个Redis自带的原子性的操作命令:

setnx key value nx ex 100

时间单位是秒

万一释放错锁了怎么办?

看这么一个场景:

0ccdfa4038a534f87c9d819403f81158.jpeg

涉及到两个问题:

  • 任务还没处理完锁就过期释放了

  • 释放掉了别人的锁

对应的解决办法:

  • 锁的续约(根据业务加长时间,并且每过一段时间访问锁,如果存在就续约,增加时间)

  • 给每个锁区分一下,这是谁加的锁(锁的value可以设置UUID等唯一确定的值)

优化过后的:

5a2b5d8b80303ccd7e12d45eeee3f6b4.jpeg

lua实现原子性

上面的一步删除的时候会发生什么错误?

e0143a227c2d19f6294059c8825d7f84.jpeg

当然 这个问题上面已经解决了,就是UUID+线程id作为key,已经不会被其他线程删掉了,但是这么看来这种错误也是挺危险的,作为一个兜底方案,我们可以用lua脚本实现原子性

lua脚本可以这么写

5753dffdad13ab691aa1a3cf576f4902.jpeg

最后的防御

分布式系统NPC

https://www.cnblogs.com/huilei/p/15916861.html

分布式系统最大的敌人可能就是NPC了,在这里它是Network Delay, Process Pause, Clock Drift的首字母缩写。我们先看看具体的NPC问题是什么:

  • Network Delay ,网络延迟。虽然网络在多数情况下工作的还可以,虽然TCP保证传输顺序和不会丢失,但它无法消除网络延迟问题。

  • Process Pause ,进程暂停。有很多种原因可以导致进程暂停:比如编程语言中的GC(垃圾回收机制)会暂停所有正在运行的线程;再比如,我们有时会暂停云服务器,从而可以在不重启的情况下将云服务器从一台主机迁移到另一台主机。我们无法确定性预测进程暂停的时长,你以为持续几百毫秒已经很长了,但实际上持续数分钟之久进程暂停并不罕见。

  • Clock Drift ,时钟漂移。现实生活中我们通常认为时间是平稳流逝,单调递增的,但在计算机中不是。计算机使用时钟硬件计时,通常是石英钟,计时精度有限,同时受机器温度影响。为了在一定程度上同步网络上多个机器之间的时间,通常使用NTP协议将本地设备的时间与专门的时间服务器对齐,这样做的一个直接结果是设备的本地时间可能会突然向前或向后跳跃。

详见这篇文章:

https://zhuanlan.zhihu.com/p/341630692

NPC三个问题都是客观存在且无法消除的,没有完全安全的分布式锁(所以大家还是要根据业务来)

上面的场景中,主节点挂了咋办?

因为Redis是AP架构的,也就是说不能保证高一致性,主节点里的锁也许并没有同步到从节点里

这里可以用Redis官方的Red Lock 保证当前hash算法选择的节点的主从都有key了才会返回true

这种做法也有点“重”了,有些时候,杀鸡焉用牛刀


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

a2bd54f85a6f1000c89636236393e26b.png

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

86c0f495fa262388f07d7fd1e1c76fe7.png

3a5e97dcf8c43e6393d810ffebe23c69.png5a95e8d70443134dbfd0423607c3f6c7.png6c220352c449075b9239f63b943de865.png0c5f1932a0f357667cacaa0d8a8f416a.png

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值