您的当前位置:首页 >知识 >Redis 如何实现分布式锁? 正文

Redis 如何实现分布式锁?

时间:2025-11-04 08:05:57 来源:网络整理编辑:知识

核心提示

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

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

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

分布式锁实现

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

复制127.0.0.1:6379> setnx lock true (integer) 1 #创建锁成功 #逻辑业务处理... 127.0.0.1:6379> del lock (integer) 1 #释放锁1.2.3.4.5.

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

复制127.0.0.1:6379> setnx lock true # 第一次加锁 (integer) 1 127.0.0.1:6379> setnx lock true # 第二次加锁 (integer) 01.2.3.4.

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

分布锁问题

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

此时,我们解决死锁问题可以通过添加设置锁的过期时间来实现。也就是 setnx 和 expire 配合使用,在 Redis 2.6.12 版本之后,新增了一个强大的功能,我们可以使用一个原子操作也就是一条命令来执行 setnx 和 expire 操作了,实现命令如下:

复制127.0.0.1:6379> set lock true ex 30 nx OK #创建锁成功 127.0.0.1:6379> set lock true ex 30 nx (nil) #在锁被占用的时候,企图获取锁失败1.2.3.4.

其中 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、设计模式、消息队列等模块。

服务器租用