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

参考资料

相关面经

54 篇

阿里巴巴

后端开发 / Agent 开发
秋招二面
查看原面经 →
如何保证分布式锁加锁操作的原子性?
如何保证谁加锁谁解锁?
如何避免 A 请求误删 B 请求的锁?

华鲲振宇

AI 开发
秋招一面
查看原面经 →
redis怎么做分布式锁?

快手

AI 应用开发
二面
查看原面经 →
分布式锁用 Redis 怎么实现,会有什么问题

阳光保险

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

水滴公司

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

百度

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

快手

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

网易云音乐

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

字节跳动

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

美的

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

美团

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

字节跳动、米哈游、哔哩哔哩、百度、美团、智驾新程、CVTE

面经合集
查看原面经 →
什么是 Redis 分布式锁?如何使用 SET NX EX 实现?释放分布式锁时为什么通常需要 Lua 脚本?

字节跳动

AI 应用开发
社招一面、二面
查看原面经 →
Redis怎么实现分布式锁

去哪儿

AI 应用开发
校招秋招
查看原面经 →
Redis 实现基础分布式锁,核心命令、关键参数怎么设计?

蔚来

智能制造软件开发实习生
实习二面
查看原面经 →
Redis互斥锁工程上如何实现

唯智信息

Java 开发实习生
实习一面
查看原面经 →
看你项目中写了分布式锁,怎么用的?

乐元素

后端开发
校招秋招一面
查看原面经 →
然后继续问分布式锁。
TTL 应该设置多长

高途

后端开发
校招秋招一面
查看原面经 →
Redis:Lua 脚本为什么能保证原子性、分布式锁释放为什么也要 Lua

科大讯飞

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

知乎

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

字节跳动

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

字节跳动

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

小红书

AI 后端开发
一面
查看原面经 →
Redis分布式锁
如果设计分布式锁,需要考虑什么?
TTL多久?
NX? EX? 你要是不用Redisson,怎么实现分布式锁??

知乎

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

字节跳动

后端开发实习生
暑期实习一面、二面、三面、四面
查看原面经 →
刚才你提到使用了分布式锁,这个锁在哪?

字节跳动

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

公司未注明

AI 应用开发
一面、二面
查看原面经 →
说明 Redis 如何通过分布式锁将并发转为串行

原力健康

Agent开发
查看原面经 →
Redis 分布式锁讲一下。

公司未注明

Java 后端开发
实习
查看原面经 →
Redis 分布式锁的实现原理是什么?
Lua 脚本在释放锁时解决什么问题?

法大大

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

用友、太平洋网络

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

MiniMax、腾讯、百度、滴滴、快手、蚂蚁集团

面经合集实习
查看原面经 →
分布式锁实现

京东

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

阿里巴巴

AI Infra 实习生
实习暑期一面
查看原面经 →
如何用Redis实现分布式锁,衍生了一堆场景

蚂蚁集团

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

蚂蚁国际

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

蚂蚁集团

AI后端开发
实习一面
查看原面经 →
如何用Redis实现分布式锁?
为什么必须用lua,不用lua会有什么问题?

大麦

Agent开发
实习一面
查看原面经 →
分布式锁怎么设计,如果有本地缓存和分布式缓存,如何保证数据一致性

阿里巴巴

暑期实习一面
查看原面经 →
为什么 Redis 可以实现分布式锁?底层原理是什么?

腾讯

AI 应用开发实习生
实习一面
查看原面经 →
在 Redis 里的分布式锁,它是大概是什么样的以及怎么用的?

重庆开源共创科技

一面
查看原面经 →
用 Redis 如何实现分布式锁呢?

腾讯

后端开发实习生
实习一面、二面、三面
查看原面经 →
怎么实现一个分布式锁,设置超时时间?

京东

AI 后端开发
一面
查看原面经 →
Redis分布式锁

字节跳动

面经合集实习
查看原面经 →
使用Redis分布式锁会遇到哪些问题?

美团

AI 软件开发实习生
实习暑期一面
查看原面经 →
如何实现分布式锁,setNX的key值如何设计,为什么

字节跳动

Agent 后端开发实习生
实习暑期一面
查看原面经 →
分布式锁?

公司未注明

Go 后端开发
一面
查看原面经 →
Redis 分布式锁

腾讯

后台开发
一面
查看原面经 →
知道redisson分布式锁是怎么实现的吗?setnx为什么能实现这个功能?为什么两个并发获取锁,最后只有一个能获取成功?
单Redis使用分布式锁要注意哪些问题,有了解过吗?加锁之间setnx就行吗?假设加锁成功,但是释放锁时进程崩了,锁没释放掉,那是不是永远就释放不掉了?

虾皮

Data Infra OLAP 实习生
日常实习一面
查看原面经 →
项目中分布式锁的使用方式
分布式锁的使用方式

腾讯

后台开发
暑期实习一面
查看原面经 →
分布式锁原理大概是什么?

快手

后端开发
二面
查看原面经 →
redis实现分布式锁 (自己实现redis分布式锁考虑什么)

懂车帝

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

网易

服务端开发
实习
查看原面经 →
redis如何实现分布式锁
追问
set命令中的value如何取的
追问
如何知道分布式锁过期时间

百度

Go 后端开发
实习一面
查看原面经 →
xx中的分布式锁与缓存一致性如何处理?

收录题集

2 个来源,共2 份题集

相关题目

4 题