Redis 如何实现分布式锁?

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

首先来说 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 #释放锁

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

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 操作了,实现命令如下:

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

责任编辑:武晓燕 来源: Java中文社群
相关推荐

2024-10-07 10:07:31

2024-04-01 05:10:00

Redis数据库分布式锁

2022-01-06 10:58:07

Redis数据分布式锁

2019-02-26 09:51:52

分布式锁RedisZookeeper

2019-06-19 15:40:06

分布式锁RedisJava

2021-11-01 12:25:56

Redis分布式

2022-08-11 18:27:50

面试Redis分布式锁

2020-07-30 09:35:09

Redis分布式锁数据库

2020-07-15 16:50:57

Spring BootRedisJava

2024-01-02 13:15:00

分布式锁RedissonRedis

2023-03-01 08:07:51

2023-01-13 07:39:07

2019-12-25 14:35:33

分布式架构系统

2023-10-11 09:37:54

Redis分布式系统

2024-02-20 09:50:02

Redis分布式

2021-10-25 10:21:59

ZK分布式锁ZooKeeper

2024-11-28 15:11:28

2022-09-19 08:17:09

Redis分布式

2020-11-16 12:55:41

Redis分布式锁Zookeeper

2021-06-16 07:56:21

Redis分布式
点赞
收藏

51CTO技术栈公众号