首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何使用Redis实现分布式锁?

如何使用Redis实现分布式锁?

原创
作者头像
磊哥
发布于 2023-08-21 11:44:08
发布于 2023-08-21 11:44:08
5590
举报
文章被收录于专栏:王磊的博客王磊的博客

首先来说 Redis 作为一个独立的三方系统,其天生的优势就是可以作为一个分布式系统来使用,因此使用 Redis 实现的锁都是分布式锁,理解了这个概念才能看懂本文所说的内容。

分布式锁的示意图,如下所示:

分布式锁实现

使用 Redis 实现分布式锁,可以通过 setnx(set if not exists)命令实现,当我们使用 setnx 创建键值成功时,则表明加锁成功,否则既代码加锁失败。因为 Redis 主线程是单线程运行的,所以也不会有同时加锁成功的情况。

实现命令如下:

代码语言:text
AI代码解释
复制
127.0.0.1:6379> setnx lock true
(integer) 1 #创建锁成功
#逻辑业务处理...
127.0.0.1:6379> del lock
(integer) 1 #释放锁

当我们重复加锁时执行结果如下:

代码语言:text
AI代码解释
复制
127.0.0.1:6379> setnx lock true # 第一次加锁
(integer) 1
127.0.0.1:6379> setnx lock true # 第二次加锁
(integer) 0

从上述命令中可以看出,我们可以使用执行的结果是否为 1 来判断加锁是否成功。

分布锁问题

然而,使用 setnx 实现分布锁有一个【死锁问题】,就是当加锁的线程(或应用)掉电或崩溃之后,其他线程只能无限等待下去的问题。

此时,我们解决死锁问题可以通过添加设置锁的过期时间来实现

也就是 setnx 和 expire 配合使用,在 Redis 2.6.12 版本之后,新增了一个强大的功能,我们可以使用一个原子操作也就是一条命令来执行 setnx 和 expire 操作了,实现命令如下:

代码语言:text
AI代码解释
复制
127.0.0.1:6379> set lock true ex 30 nx
OK #创建锁成功
127.0.0.1:6379> set lock true ex 30 nx
(nil) #在锁被占用的时候,企图获取锁失败

其中 ex 为设置超时时间, nx 为元素非空判断,用来判断是否能正常使用锁的。

小结

Redis 作为一个独立的三方系统,其优势是天生可以实现分布式锁。它实现分布式锁是通过 setnx 来实现的,然而只有 nx(not exists)可能会发生死锁的问题,所以我们最终实现死锁应该使用 set nx ex 的方式来实现。

小思考:当设置了过期时间之后,Redis 实现分布式依然会有一个小小的问题,有人知道这个问题和解决方案吗?欢迎评论区写出你的答案。 此文章点赞过 100,我会给出标准答案。

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
从线上分布式锁的使用到深度理解redis分布式锁
关于分布式锁,相信大家都用的非常普遍。分布式锁其实就是控制分布式系统间不同的服务,不同的进程或者不同的线程共享同一资源的一种方式。当共享资源被竞争,我们需要通过互斥来防止彼此干扰从而保证一致性,这个时候我们就需要使用分布式锁。
公众号-利志分享
2022/04/25
3490
面试官:怎么实现Redis分布式锁?
在单机环境下,当存在多个线程可以同时改变某个变量(可变共享变量)时,就会出现线程安全问题。这个问题可以通过 JAVA 提供的 volatile、ReentrantLock、synchronized 以及 concurrent 并发包下一些线程安全的类等来避免。
程序员大彬
2022/07/08
4080
Redis 做分布式锁你会几种姿势?
Redis 简简单单的几种数据类型,一个 key/value 数据库,现在又是分布式锁、又是限流工具、又是消息队列......,感觉都要被玩坏了。不过话说回来,Redis 在这么多场合被开发者们喜欢,还是得益于它极高的性能与使用的简洁性。
江南一点雨
2020/03/16
5720
Redis 之分布式锁的实现
我们在系统中修改已有数据时,需要先读取,然后进行修改保存,此时很容易遇到并发问题。由于修改和保存不是原子操作,在并发场景下,部分对数据的操作可能会丢失。在单服务器系统我们常用本地锁来避免并发带来的问题,然而,当服务采用集群方式部署时,本地锁无法在多个服务器之间生效,这时候保证数据的一致性就需要分布式锁来实现。
架构狂人
2023/08/16
9510
Redis 之分布式锁的实现
Redis系列(二):Redis的分布式锁解析及应用
在开发中,一个进程中多个线程需要竞争某一资源的时候,我们通常会用一把锁来保证只有一个线程获取到资源。如加上synchronize关键字或ReentrantLock锁等操作。但如果是多个进程相互竞争一个资源,如何保证资源只会被一个操作者持有呢?
鳄鱼儿
2024/05/21
1940
深入理解分布式锁
假设这里有一个分布式应用,它拥有多个客户端,每个客户端都会对存储在Redis中的数据进行计算并修改,计算的前提是获取到最新的数据,然后进行计算,最后写回Redis。在一个不存在并发的程序中,程序可以直接读取Redis中的数据进行计算并写回结果,也不会产生什么问题,因为计算的过程是一个串行的过程,但是如果在一个并发环境中,多个客户端完全存在并行读取,并行写入的情景,那么就可能会产生并发问题,导致最终计算的数据产生偏差。
itlemon
2020/04/03
4870
深入理解分布式锁
012:Redis分布式锁
比如一个操作要修改用户的状态,修改状态需要先读出用户的状态,在内存里进行修 改,改完了再存回去。如果这样的操作同时进行了,就会出现并发问题,因为读取和保存状态这两个操作不是原子的。(Wiki 解释:所谓 原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch 线程切换。)
李玺
2021/11/22
8820
012:Redis分布式锁
基于Redis实现的分布式锁
Spring Cloud 分布式环境下,同一个服务都是部署在不同的机器上,这种情况无法像单体架构下数据一致性问题采用加锁就实现数据一致性问题,在高并发情况下,对于分布式架构显然是不合适的,针对这种情况我们就需要用到分布式锁了。
不会飞的小鸟
2020/05/03
4430
深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!
因为我发现网上 99% 的文章,并没有把这个问题真正讲清楚。导致很多读者看了很多文章,依旧云里雾里。例如下面这些问题,你能清晰地回答上来吗?
_Kaito
2021/06/25
9141
深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!
Redis如何实现分布式锁?
如果在一个分布式系统中,我们从数据库中读取一个数据,然后修改保存,这种情况很容易遇到并发问题。因为读取和更新保存不是一个原子操作,在并发时就会导致数据的不正确。这种场景其实并不少见,比如电商秒杀活动,库存数量的更新就会遇到。如果是单机应用,直接使用本地锁就可以避免。如果是分布式应用,本地锁派不上用场,这时就需要引入分布式锁来解决。
java技术爱好者
2021/03/15
3510
浅谈分布式锁
分布式锁就是在分布式系统中,为解决共享资源排他性式访问而设定的锁。用于解决分布式系统中操作共享资源数据一致性问题。
灬沙师弟
2023/09/06
3390
浅谈分布式锁
厉害了,原来分布式锁有这么多坑
并发环境下,多个系统相互协作,不可避免的,总是会有很多工作需要协调进行,此时就必须要引入分布式事务来进行整个任务的协调统筹,关于分布式事务的解决方案,我们已经进行过详细介绍。 分布式事务通用解决方案
用户3147702
2022/06/27
6900
厉害了,原来分布式锁有这么多坑
Redis-分布式锁
https://mp.weixin.qq.com/s/RnSokJxYxYDeenOP_JE3fQ
Get
2024/03/10
2120
基于 Redis 实现的分布式锁
Spring Cloud 分布式环境下,同一个服务都是部署在不同的机器上,这种情况无法像单体架构下数据一致性问题采用加锁就实现数据一致性问题,在高并发情况下,对于分布式架构显然是不合适的,针对这种情况我们就需要用到分布式锁了。
南风
2020/06/09
9470
基于 Redis 实现的分布式锁
Redis的“假事务”与分布式锁
我们在学习MySQL的存储殷勤时知道,MySQL中innodb支持事务而myisam不支持事务。而事务具有四个特性:
用户1148394
2020/02/26
7320
2023-06-19:讲一讲Redis分布式锁的实现?
要实现分布式锁,确实需要使用具备互斥性的Redis操作。其中一种常用的方式是使用SETNX命令,该命令表示"SET if Not Exists",即只有在key不存在时才设置其值,否则不进行任何操作。通过这种方式,两个客户端进程可以执行SETNX命令来实现互斥,从而达到分布式锁的目的。
福大大架构师每日一题
2023/08/29
3330
2023-06-19:讲一讲Redis分布式锁的实现?
「分布式」实现分布式锁的正确姿势
最近看到好多博主都在推分布式锁,实现方式很多,基于db、redis、zookeeper。zookeeper方式实现起来比较繁琐,这里我们就谈谈基于redis实现分布式锁的正确实现方式。
一个程序员的成长
2020/11/25
9030
「分布式」实现分布式锁的正确姿势
谈谈基于Redis的分布式锁
在我们没有了解分布式锁前,使用最多的就是线程锁和进程锁,但他们仅能满足在单机jvm或者同一个操作系统下,才能有效。跨jvm系统,无法满足。因此就产生了分布式锁,完成锁的工作。
一个风轻云淡
2023/11/25
6000
Java手写分布式锁的实现(非常牛逼)
我们可以借助于redis中的命令setnx(key, value),key不存在就新增,存在就什么都不做。同时有多个客户端发送setnx命令,只有一个客户端可以成功,返回1(true);其他的客户端返回0(false),流程图如下图所示:
芋道源码
2023/11/17
7140
Java手写分布式锁的实现(非常牛逼)
Redis 怎样实现的分布式锁?
“锁”是我们实际工作和面试中无法避开的话题之一,正确使用锁可以保证高并发环境下程序的正确执行,也就是说只有使用锁才能保证多人同时访问时程序不会出现问题。
码农架构
2021/02/23
3360
Redis 怎样实现的分布式锁?
相关推荐
从线上分布式锁的使用到深度理解redis分布式锁
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档