Redis 如何实现分布式锁

课程地址

单机 Redis

naive 版

加锁:

bash 复制代码
SETNX ${lockName} ${value}	# set if not exist

如果不存在则插入成功,返回 1,加锁成功;否则返回 0,加锁失败

解锁:

bash 复制代码
DEL ${lockName}

问题1

2 个线程 A、B,线程 A 拿到了锁后,宕机了怎么办?谁来释放锁?

解决:使用自动过期机制:

加锁:

bash 复制代码
SET ${lockName} ${value} EX 10 NX	# atomic opreation

解锁:

bash 复制代码
DEL ${lockName}

问题2

t0 时刻实例1获取到锁,t3 时刻被自动释放(国企),同时实例2获取到锁,t4 时刻实例1再次释放(实例2的锁),实例3又获取到了锁,造成了数据混乱

解决:设置 value 为当前实例线程 id,在解锁时做判断

加锁:

bash 复制代码
SET ${localName} ${threadId} EX 10 NX

解锁(使用 lua 脚本实现原子性):

lua 复制代码
current_value = get ${lockName}
if ${threadId} == current_value then
	DEL ${lockName}

问题3

锁被自动释放的问题仍然存在

启动一个异步线程(WatchDog),获取到锁成功后启动异步线程,每隔 x 秒对当前锁续期 y 秒,直到锁被释放停止

至此,单机版的 Redis 分布式锁就得到了成功实现

集群 Redis

主节点加锁成功后崩溃,从节点上位后没有锁的信息

加锁:

  • 向所有节点发送加锁请求
  • 获取到锁的数量达到节点个数半数以上认为加锁成功

解锁:

删除所有实例上的锁

问题4

网络延迟超过了锁的过期时间

加锁:

一、获取当前时间

二、按顺序依次向N个Redis实例执行加锁操作

这里的加锁操作和在单实例上执行的加锁操作一样,使用SET命令,带上NX、EX/PX选项,以及带上客户端的唯一标识。当然,如果某个Redis实例发生故障了,为了保证在这种情况下,Redlock算法能够继续运行,我们需要给加锁操作设置一个超时时间。如果客户端在和一个Redis实例请求加锁时,一直到超时都没有成功,那么此时,客户端会和下一个Redis实例继续请求加锁。加锁操作的超时时间需要远远地小于锁的有效时间,一般也就是设置为几十毫秒

三、一旦客户端完成了和所有Redis实例的加锁操作,客户端就要计算整个加锁过程的总耗时

客户端只有在满足两个条件时,才能认为是加锁成功:

  • 客户端从超过半数(大于等于 N/2+1)的Redis实例上成功获取到了锁
  • 客户端获取锁的总耗时没有超过锁的有效时间

在满足了这两个条件后,我们需要重新计算这把锁的有效时间,计算的结果是锁的最初有效时间减去客户端为获取锁的总耗时。如果锁的有效时间已经来不及完成共享数据的操作了,我们可以释放锁,以免出现还没完成共享资源操作,锁就过期了的情况。

当然,如果客户端在和所有实例执行完加锁操作后,没能同时满足这两个条件,那么,客户端就要向所有Redis节点发起释放锁的操作

相关推荐
yandong6343 小时前
redis添加到win服务
数据库·redis·缓存
我叫小米粒4 小时前
可维护的智能体协作空间:字段建模、提示约束、测试集和上线检查
数据库·aigc·agent·智能体交付
数智启示录4 小时前
Flink CDC 机制精讲(四):一条 SQLServer CDC 事件如何保持顺序 【面试宝典】
数据库·面试·sqlserver·flink
攻城有术4 小时前
专项攻克——redis分布式锁-用LUA脚本解决setNX锁不释放问题
redis·分布式·lua
张文君4 小时前
ubuntu26.04从ext4到raid1+lvm启动-最终版-有这个方法系统损坏还焦虑个啥
数据库
今天AI了吗4 小时前
AI工作流的自动化趋势:从手动实验到自主Agent的研究范式转变
运维·数据库·人工智能·sql·机器学习·自动化·github
Wang's Blog4 小时前
Vibe Coding一人即团队系列28: 前端、后端与数据库的概念解析
前端·数据库
安全指北针4 小时前
IDC《中国数据安全技术发展路线图,2025》:数据安全管理平台推荐厂商
大数据·数据库·人工智能
瀚高PG实验室4 小时前
PostgreSQL CREATE TYPE 未检查 multirange schema 的 CREATE 权限HGVE-2026-E007
数据库·postgresql·瀚高数据库
xfan_me4 小时前
手机在网状态接口-空号查询-空号过滤API
数据库·人工智能·python·智能手机