首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >从线上分布式锁的使用到深度理解redis分布式锁

从线上分布式锁的使用到深度理解redis分布式锁

作者头像
公众号-利志分享
发布于 2022-04-25 01:24:36
发布于 2022-04-25 01:24:36
3860
举报
文章被收录于专栏:利志分享利志分享

关于分布式锁,相信大家都用的非常普遍。分布式锁其实就是控制分布式系统间不同的服务,不同的进程或者不同的线程共享同一资源的一种方式。当共享资源被竞争,我们需要通过互斥来防止彼此干扰从而保证一致性,这个时候我们就需要使用分布式锁。

这篇文章我主要分享通过redis来实现分布式锁的方式,以及存在的问题。

setnx命令

代码语言:javascript
AI代码解释
复制
set if not exists

设置一个值,或者填一个坑,设置完了或者填完了就没有了,只有del才能释放。

线上案例分享:

我们线上分布式锁就是使用的setnx,有一次因为线上问题,我们强制重启了一个服务,造成后面重启之后a数据一直没拿到。a数据只能让某一个服务能拿到。这个获取就是通过setnx实现的,因为a数据只能启动后一个服务获取到。后面查了许久才明白过来setnx执行之后,del没有执行成功,造成陷入死锁。像这种问题我们如何避免呢?是不是加个过期时间才能解决?其实过期时间也是会存在同样的问题,如果setnx成功,但是expire执行失败了,那还是同样会有问题。

总结案例:

使用setnx来控制并发,del或者expire的使用能一定程度上解决死锁的问题,但是如果两个命令有一个执行失败,那死锁就来了,就出现问题了。我们看到使用setnx存在的问题,我们想只有保证setnx和del或者setnx和expire原子性操作才能保证一定不会死锁。setnx和del是无法做到原子性的,但是set和expire则可以,这样我们就引入另外一个处理命令。

代码语言:javascript
AI代码解释
复制
set lock x EX 10 NX

这个命令表示只有不存在key为lock才设置,有效时间是10s。这个命令是原子性的,从redis2.6.12版本开始支持。是不是以为这个命令实现分布式锁就是完美的了?并不是!使用这个只是说相对来说比较安全。为什么这么说,因为如果一个锁里面的执行超过了设置锁的超时时间,可能临界取区域的代码并不是安全的执行,这样可能其他线程或者服务就会同时操作同一份数据。

总结:

  • setnx结合expire或者del命令并不是原子性的。
  • SET key value [EX seconds] [PX milliseconds] [NX|XX] 这个命令是原子性的,但是使用需要注意执行的数据是否超过过期时间。

祝大家中秋快乐~~~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 利志分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
首页
学习
活动
专区
圈层
工具
MCP广场
首页
学习
活动
专区
圈层
工具
MCP广场