怎样实现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, ZLW的头像Z, ZLW
上一篇 2023年1月8日 上午4:03
下一篇 2023年1月8日 上午4:39

相关推荐

  • 管理类项目应用领域有哪些

    管理类项目应用领域广泛且多样,涵盖了各个行业和领域。首先,科技行业,例如软件开发、网络安全、人工智能等,都需要用到项目管理的知识和技能。其次,建筑行业,包括建筑设计、施工、装修等,都需要进行项目管理。再者,教育行业,包括学校管理、课程设计、教学改革等,也需要进行项目管理。另外,医疗行业,如医院管理、…

    2024年8月3日
    100
  • 项目总承包的管理方法有哪些

    项目总承包的管理方法主要包括:明确项目目标、设计合理的项目计划、设置明确的执行标准、进行有效的风险管理、建立有效的沟通机制、持续的项目监控、采取灵活的变更管理、实施全面的质量控制、进行科学的成本控制和使用先进的项目管理工具。其中,设计合理的项目计划是基础,它涵盖了项目的时间、资源和成本等关键因素。项…

    2024年8月3日
    000
  • 芯片项目管理工作内容有哪些

    芯片项目管理的工作内容主要包含以下几个方面:1、项目计划制定和执行;2、团队协调和管理;3、进度跟踪和控制;4、风险识别和处理;5、质量控制和保证;6、成本和资源控制;7、通信和信息管理;8、供应链管理。 首先,项目计划的制定和执行是芯片项目管理的基础环节。在该环节中,项目经理需要根据项目的目标和需…

    2024年8月3日
    000
  • 十个项目管理新术语有哪些

    在现今的项目管理中,有十个新的术语正在广泛使用,包括敏捷管理、瀑布模型、Scrum、Kanban、Lean、DevOps、Jira、Git、PingCode、Worktile等。其中,PingCode是一款专注于企业级应用开发的云端一体化开发平台,帮助企业快速构建、部署和运行应用程序。它的出现,使得…

    2024年8月3日
    000
  • 项目风险管理的风险类型有哪些

    项目风险管理中的风险类型主要包括:技术风险、财务风险、合同风险、市场风险、组织风险、政策风险等。其中,技术风险是项目风险管理中最常见的风险类型,它包含了技术实现难度大、技术研发不成熟、技术更新快等风险。这些风险可能导致项目无法按计划进行,严重时甚至会导致项目失败。例如,如果一个项目的技术实现难度大于…

    2024年8月3日
    000

发表回复

登录后才能评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

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

分享本页
返回顶部