怎样实现redis分布式锁

实现redis分布式锁的步骤:1、加锁;2、释放锁;3、给锁设置有效期;4、给锁设置少数值;5、通过LUA脚本实现释放锁的原子性。加锁是指,执行 setnx 为一个代表锁键设置值,如果能设置成功,则表示获得锁,失败则无法获得锁。

怎样实现redis分布式锁-Worktile社区

1、加锁

Redis 的 setnx 命令会判断键值是否存在,如果存在则不做任何操作,并返回0,如果不存在,则创建并赋值,并返回1,因此我们可以执行 setnx 为一个代表锁键设置值,如果能设置成功,则表示获得锁,失败则无法获得锁。

代码:

# 使用key为lock来表示一个锁
setnx lock 1 

2、释放锁

当执行好操作之后,要释放锁的时候直接把 Redis 里的键值 lock 删除就可以了,这样其他进程才能通过 setnx 命令重新设置并获得该锁。

代码:

# 释放锁
del lock

通过上面两个命令,我们实现了一个简单的分布式锁,但这里就出现了一个问题:如果一个进程通过 setnx 命令加锁之后,在执行具体操作出错了,没有办法及时释放锁,那么其他进程就无法获得该锁,系统便无法继续往下执行,解决这个问题的办法就是为锁设置一个有效期,在这个有效期之后,自动释放锁。

3、给锁设置有效期

给锁设置有效期非常简单,直接使用 Redis 的 expire 命令就可以了,如:

# 加锁
setnx lock 1 
# 给锁设置10s有效期
expire lock 10 

但是,现在又出现另一个问题了,如果我们在设置了锁之后,执行 expire 命令之前该进程挂掉了,那么 expire 就没有执行成功,锁一样是没有被释放掉的,所以一定要保证上面两个命令要一起执行,怎么保证呢?

有两个方法,一个是使用 LUA 语言编写的脚本,另一个是使用 Redis 的 set 命令, set 命令后面跟 nx 参数后,执行的效果与 setnx 一致,且 set 命令可以跟 ex 参数来设置过期时间,所以我们可以使用 set 命令把 setnx 和 expire 两个合并在一起,这样就可以保证执行的原子性了。

4、给锁设置少数值

如何区分其他进程的锁,避免删除其他进程的锁呢?答案就是每个进程在加锁的时候,给锁设置一个少数值,并在释放锁的时候,判断是不是自己设置的锁。给锁设置少数值的时候,一样是使用 set 命令,少数的不同是将键值1改为一个随机生成的少数值,比如uuid。

代码:

 # rand_uid表示少数id
set lock rand_id nx ex 10

当锁里的值由进程设置后,释放锁的时候,就需要判断锁是不是自己的,步骤如下:

  • 通过 Redis 的 get 命令获得锁的值
  • 根据获得的值,判断锁是不是自己设置的
  • 如果是,通过 del 命令释放锁。

此时我们看到,释放锁需要执行三个操作,如果三个操作依次执行的话,是没有办法保证原子性的。解决这个问题的办法就是保证上述三个操作执行的原子性,即在执行释放锁的三个操作中,其他进程不可以获得锁,想要做到这一点,需要使用到LUA脚本。

5、通过LUA脚本实现释放锁的原子性

Redis 支持 LUA 脚本, LUA 脚里的代码执行的时候,其他客户端的请求不会被执行,这样可以保证原子性操作,所以我们可以使用下面脚本进行锁的释放:

if redis.call("get",KEYS[1]) == ARGV[1] then 
  return redis.call("del",KEYS[1])
else 
  return 0
end

将上述脚本保存为脚本后,可以调用 Redis 客户端命令 redis-cli 来执行,如下:

# lock为key,rand_id表示key里保存的值
redis-cli --eval unlock.lua lock , rand_id 

延伸阅读

分布式锁的特征

  • 互斥性:任意时刻,只有一个客户端能持有锁。
  • 锁超时释放:持有锁超时,可以释放,防止不必要的资源浪费,也可以防止死锁。
  • 可重入性:一个线程如果获取了锁之后,可以再次对其请求加锁。
  • 高性能和高可用:加锁和解锁需要开销尽可能低,同时也要保证高可用,避免分布式锁失效。
  • 安全性:锁只能被持有的客户端删除,不能被其他客户端删除

文章标题:怎样实现redis分布式锁,发布者:Z, ZLW,转载请注明出处:https://worktile.com/kb/p/34703

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
Z, ZLWZ, ZLW认证作者
上一篇 2023年1月8日 上午4:03
下一篇 2023年1月8日 上午4:39

相关推荐

  • DevOps和Agile开发的主要区别是什么

    DevOps与Agile开发两者都旨在提高软件开发效率和交付质量,但它们侧重的领域不同。该文章将阐述两者主要区别所在:1、基本哲学差异;2、流程和实践的不同;3、目标和重点差别;4、工作文化和团队结构。Agile强调增量开发和频繁反馈,而DevOps注重开发与运维团队的协作,以实现软件的快速交付和高…

    2023年12月13日
    16400
  • 产品经理与项目经理的区别是什么

    产品经理与项目经理在责任、技能以及工作重点上存在显著区别。1、职责焦点有别:产品经理主要关注产品从构思到市场的整个生命周期,包括定义产品愿景和战略、理解用户需求、定义产品特性等,而项目经理负责规划、执行、监控和完成具体项目,重点管理项目进度、预算和资源。2、角色定位不同:产品经理担当用户与技术团队之…

    2023年12月19日
    14700
  • 敏捷开发中的团队协作有哪些关键要点

    敏捷开发中的团队协作的关键要点有交流和沟通、自组织和跨职能团队、迭代和增量开发、用户参与和反馈、透明和可视化、持续改进、高度合作和互信、快速反应和适应变化、持续集成和自动化测试、高效决策和冲突解决、资源和风险管理、培养团队精神和共同目标等。详细介绍:1、交流和沟通,团队成员之间的交流和沟通是敏捷开发中最重要的要点之一;2、自组织和跨职能团队等等。

    2023年10月23日
    31800
  • okr怎么做|OKR

    标题:OKR怎么做 摘要:OKR(Objectives and Key Results)是一种目标设定框架,用以提升组织、团队或个人的执行力和成果导向性。有效执行OKR通常包括几个步骤:1、明确目标(Objectives)、2、设定关键成果(Key Results)、3、制定具体行动计划、4、定期检…

    2024年1月17日
    6400
  • 需求管理怎么考核

    需求管理考核应该包含:一、需求收集的效率;二、需求分析的质量;三、需求规划的合理性;四、需求跟踪的及时性;五、需求控制的效果。需求收集是需求分析的基础,如果收集不到准确的需求,后续的需求管理就会出现问题。 一、需求收集的效率 需求收集是需求分析的基础,如果收集不到准确的需求,后续的需求管理就会出现问…

    2023年4月30日
    36400
  • 进度计划编制软件哪个好

    好用地进度计划编制软件有:1、Worktile;2、PingCode;3、Teambition;4、TAPD;5、Jira;6、蚂蚁分工;7、Slack;8、Notion。Worktile是一个在业务部门或者产品部门都可以使用企业级项目协作与目标管理软件。 1、Worktile Worktile是一…

    2023年4月14日
    78100
  • 如何将OKR融入企业文化和日常运营

    OKR(Objective and Key Results)的融合对于增强企业文化与提升日常运营效率至关重要。1、定义明确的目标和关键结果要确保与企业文化相匹配,鼓励团队协作和个人责任感。2、提供持续的培训和支持能够帮助员工理解和实施OKR。3、设置透明的沟通渠道让信息自由流动,确保每位员工了解公司…

    2023年12月8日
    17100
  • 为什么720p,480p,1080p文件大小相差了不止一倍

    720p,480p,1080p文件大小相差了不止一倍的原因:720p、480p、1080p等分辨率是视频的输出大小,其包含了视频的宽度和高度,在传输过程中,由于文件大小与视频编码的参数、视频压缩技术以及视频的质量的不同,它们的文件大小相差了不止一倍。 一、720p,480p,1080p文件大小相差了…

    2023年4月15日
    2.0K00
  • Java中的国际化和本地化支持如何实现

    针对Java中的国际化和本地化实现,解决策略在于1、利用 Locale 类识别用户地理位置、2、通过 ResourceBundle 管理资源文件、3、使用 MessageFormat 类格式化具有地域特色的信息、4、编写国际化应用程序代码。特别展开描述Locale 类,该类是Java中用于标识特定的…

    2024年1月8日
    10000
  • DevOps与监控工具和性能优化的关键区别

    DevOps与监控工具和性能优化都是软件工程和运维领域的重要组成部分,但它们在目标、应用范围、工具使用和实施策略上有显著不同。本文将详细讨论以下五个主要区别:1、目标和侧重点;2、应用范围和层面;3、工具和技术;4、团队和角色;5、衡量指标和评价准则。通过对比,您将更清晰地理解这两者的不同定位和应用…

    2023年9月13日
    17200

发表回复

登录后才能评论
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部