前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何通过Redis实现多系统单Redis的分布式锁

如何通过Redis实现多系统单Redis的分布式锁

作者头像
名字是乱打的
发布2022-05-13 11:13:49
2510
发布2022-05-13 11:13:49
举报
文章被收录于专栏:软件工程

分布式锁 在分布式环境中,为了保证业务数据的正常访问,防止出现重复请求的问题,会使用分布式锁来阻拦后续请求。我们先写一段有问题的业务代码:

分布式锁需要解决的问题

  • 互斥性
  • 安全性
  • 死锁
  • 容错
Redis 2.6版本之前想实现原子性需要借助两个方法
  • setnx key value:如果key不存在,则创建并赋值返回1,如果存在返回0
  • expire key time : time秒后销毁key(当time设置为0时候会直接释放该key)
那么为什么可以用这两种方法组合实现分布式锁呢?

我们可以把key理解为一个资源

  • 当这个setnx key value返回结果为0时候即赋值不成功,那么可以理解为此时资源在被占用状态,其他线程无法占用资源并执行得到资源后的操作.
  • 当这个setnx key value返回结果为1时候即赋值成功,那么可以理解为此时资源不在被占用状态,那么我们此时可以占用这个资源并执行得到资源后的操作(占用这个资源即填充资源使其他线程在尝试setnx key value返回值为0).
  • expire key time销毁资源相当于我用完资源后为了让别人可以获得这个资源(setnx key value返回值为1) 而进行的释放锁的过程

Redis2.6之后实现分布式锁的方式

由于上述方法中加锁和释放锁分别是原子的,但是两个过程组合到一起就不是原子的了,因此高并发情况下,原子性得不到满足,我们采用下面的方法去实现分布式锁 set key value ex|px nx|xx eg: set locktarget 122325 ex 10 nx

  • EX 即second:设置键的过期时间为second秒
  • PX 即millisecond:设置键的过期时间为millisecond 毫秒
  • NX:只在键不存在时,才对键进行设置操作(等同于setnx,分布式用这个) set locktarget 122325 ex 10 nx即只有nx判断locktarget不存在才会进行赋值12325返回OK
  • XX:只在键已经存在时,才对键进行设置操作
  • SET操作成功完成时,返回OK,否则返回nil
上述情况同样仍然存在一个问题,那就是如果是多线程情况下,A到了过期时间,但是此时持久A的线程还没完成任务,这时候释放了锁,被B拿走了,那么A完成任务了再执行一个del(key)。但这时候线程B还没执行完,线程A实际上删除的是线程B加的锁。

怎么办呢?我们可以让获得锁的线程开启一个守护线程(跟母线程消亡时间一致),用来给快要过期的锁“续航”。当过去了29秒,线程A还没执行完,这时候守护线程会执行expire指令,为这把锁“续命”20秒。守护线程从第29秒开始执行,每20秒执行一次。(System.currentTimeMillis() 获取两个当前时间,再取差值)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Redis2.6之后实现分布式锁的方式
    • 上述情况同样仍然存在一个问题,那就是如果是多线程情况下,A到了过期时间,但是此时持久A的线程还没完成任务,这时候释放了锁,被B拿走了,那么A完成任务了再执行一个del(key)。但这时候线程B还没执行完,线程A实际上删除的是线程B加的锁。
    相关产品与服务
    云数据库 Redis
    腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档