Redis 分布式锁的原理是什么?

考查重点:锁归属、租期与释放原子性。SET NX 租期抢锁,持有者标识配 Lua 比对释放,处理续租与旧执行者

本题目录

参考答案

核心回答

Redis 分布式锁把锁状态放在各个进程都能访问的 Redis 中,利用原子条件写入决定谁获得锁,再通过租约和持有者标识管理锁的有效期与释放。

基本流程是:

  1. 加锁:为业务资源确定同一个锁键,用一次带 NX 和 EX/PX 的 SET 写入本次获取独有的随机标识及过期时间。键不存在才成功;只有确认成功后,才执行临界区。
  2. 持有:租约限制锁的有效时间,避免客户端崩溃后永久占锁。业务可能超过租期时,需要缩短临界区或在确认仍是持有者后原子续约。
  3. 释放:比较锁值是否仍等于本次标识,再删除,比较和删除要原子完成。通常用 Lua 脚本;Redis 8.4 起也可用 DELEX 的 IFEQ 条件删除。
  4. 竞争失败:按业务选择立即失败、限时等待或带退避的重试,不要无限空转。

这套机制提供的是有期限、受故障条件约束的互斥协调。锁过期不会停止原业务线程,异步主从切换也可能丢失锁记录;重要业务约束仍需数据库条件更新、唯一约束、幂等或下游版本校验配合。

为什么要原子加锁和按标识释放?

如果先执行 SETNX,再单独设置过期时间,客户端可能在两步之间崩溃,留下没有过期时间的锁。将“键不存在才写入”和 TTL 放在同一次 SET 中,可以避免这个窗口。

释放时只执行 DEL 也有风险。假设 A 获得一把租期为 10 秒的锁,执行时发生长暂停;锁到期后 B 获得同一锁键。A 恢复后如果直接删除,就会删掉 B 的锁。因此每次获取都要有独立标识,不能只是一个固定的客户端名字。

“先在客户端 GET 比较,再发 DEL”仍存在间隙:比较后锁可能过期并被别人获得。Lua 或条件删除把比较和删除合在 Redis 内原子执行,才不会在这两步之间误删新锁。

续约能解决业务超时吗?

续约要在租约有效时进行,并原子检查当前持有者,避免替别人的锁延长时间。Redisson 的看门狗可以在自动续约模式下持续延长租期;显式指定固定 leaseTime 的使用方式应按固定租约理解,不能默认看门狗还会替它无限续约。

续约能覆盖正常的长任务,但长时间 GC、进程暂停、网络分区或 Redis 不可用,都可能使续约错过期限。进程还活着,不等于锁还有效。 租约已失效时,旧客户端应停止后续受保护操作;单次检查锁是否存在,也无法把“检查”和之后对外部系统的写入合成原子操作。

对需要拦截旧持有者迟到写的资源,可以使用单调递增的 fencing token(隔离令牌):每次获得锁带上新的代次,下游原子记录已接受的最大代次,拒绝更旧的写入。它要求令牌生成机制符合故障模型,且下游真正执行校验;普通随机锁值只能识别持有者,不能表示先后代次。

Redis 故障时有哪些边界?

单节点锁的原子命令并不能自动提供跨节点强一致。若主节点确认加锁后、锁尚未复制就故障,新主节点可能没有该锁,另一个客户端又能成功加锁。客户端请求超时也可能只是成功响应丢失,不能直接认定自己已经获得锁。

Redlock 使用多个独立 Redis 节点,结合多数节点成功和剩余租期判断获取结果,但仍有时间、暂停和故障恢复方面的前提,不等同于“部署 Redis Cluster 后锁绝对安全”。应按允许的失败后果选择协调方案,并把最终业务约束落实到受保护的资源上。

例如缓存热点重建可以用锁减少并发回源,但还需限制数据库回源量;扣库存则应由数据库条件更新和事务保证不扣成负数。Redis 锁不会自动把数据库操作或数据库与消息发送变成分布式事务。

常见追问

TTL 越长越安全吗? 更长能减少正常执行中提前过期的概率,却会延长故障后的等待。应结合临界区耗时、暂停、网络延迟和续约能力选择,并限制任务执行时间,而不是无限延长。

基本的 SET NX 锁可重入吗? 不可直接重入。同一请求再次执行也会发现键存在;可重入锁需要额外的持有者身份、重入计数和匹配的释放规则。需要这类能力时,使用已有实现,并理解它的线程归属和租约语义。

参考资料

相关面经

20 篇

阳光保险

AI 应用开发工程师
校招二面
查看原面经 →
Redis 分布式锁以及数据一致性讲一下

水滴公司

AI 全栈工程师
校招秋招一面、二面
查看原面经 →
你还写了 Redis 分布式锁的实战经验。哪个场景用到了?
锁这块是你实现的吗?展开细节讲讲,设计怎么考虑的——为什么用锁、为了防重,过期时间怎么考虑、过程中断了怎么办?
实现了幂等写入和单游戏并发锁,这个是基于什么背景去做的?

百度

AI智能体算法
一面、二面、三面
查看原面经 →
Redis 分布式锁怎样避免锁被误删?

快手

全栈实习生
实习一面
查看原面经 →
项目里面的分布式锁是怎么实现的?

网易云音乐

全栈开发 / 后端开发实习
实习秋招一面
查看原面经 →
Redis 分布式锁怎么实现?
展开剩余 15 篇面经

字节跳动

Agent 开发
校招秋招一面、二面、三面
查看原面经 →
追问
为什么不能先 `GET` 判断锁不存在,再执行 `SET`?`SET NX` 解决了什么问题?
追问
一个基本正确的 Redis 分布式锁应怎样获取?
追问
已经使用 `SET NX`,为什么释放锁还需要 Lua?为什么不能直接 `DEL`?

美的

后端开发工程师
秋招一面
查看原面经 →
你项目中的分布式锁如何实现

美团

AI 全栈开发工程师
校招秋招二面
查看原面经 →
Redis分布式锁怎么实现?锁过期了业务还没执行完怎么办

科大讯飞

Java 开发工程师
秋招一面、二面
查看原面经 →
Redis除了做缓存,还能做分布式锁,这个能讲一讲吗

知乎

全栈开发工程师
秋招一面
查看原面经 →
项目追问
redis分布式锁设计(适配项目场景)

字节跳动

后端开发工程师
一面
查看原面经 →
Redis 分布式锁应该怎么设计?

字节跳动

AI 应用开发工程师
秋招一面
查看原面经 →
追问
Redis 加锁和释放锁的原理、注意事项是什么?

知乎

后端开发
实习一面
查看原面经 →
项目问的多,具体不说了,比如lua、设计思路、逻辑、你怎么设计的, 具体的逻辑,比如lua里面的有哪些逻辑 你用Lua实现分布式锁,为什么不用Redisson的RLock?

字节跳动

AI 应用开发工程师
日常实习一面
查看原面经 →
项目追问
项目里使用 Redis 实现分布式锁,具体是怎么做的?

法大大

Java 开发工程师
实习一面
查看原面经 →
实习中你用Redis做了分布式锁,解释一下分布式锁具体怎么实现的

用友、太平洋网络

面经合集
查看原面经 →
redis分布式锁+死锁,

京东

后端开发工程师(Agent)
实习一面
查看原面经 →
分布式锁(用setnx命令实现)底层怎么实现的,了解吗?

蚂蚁集团

Agent 开发工程师
实习一面
查看原面经 →
Redis实现分布式锁的原理是什么?

蚂蚁国际

AI 应用 / Agent 开发
暑期实习一面
查看原面经 →
Redis实现分布式锁的原理是什么?

懂车帝

Agent 架构
暑期实习二面
查看原面经 →
Redis 实现分布式锁的命令 > 为什么Redis能实现分布式锁

收录题集

2 个来源,共2 份题集

相关题目

4 题