Redis 实现分布式锁时可能遇到的问题有哪些?

Redis分布式锁遇到的问题(面试Markdown结构化)

1. 加锁不原子,出现死锁

  • 问题:分开执行setexpire,set成功后Redis宕机,没设置过期时间,锁永久存在,其他线程永远拿不到锁。
  • 解决:使用set key value NX EX一条命令原子加锁。

2. 锁被其他客户端误删除

  • 问题:业务执行时间超过锁过期时间,锁自动释放;别的线程抢到锁,原线程执行del,直接删掉别人持有的锁。
  • 解决:加锁存入客户端唯一标识;释放锁用Lua脚本,校验value属于自己才删除,禁止直接del。

3. 业务没执行完,锁提前过期释放

  • 问题:业务逻辑耗时 > 锁TTL,锁过期释放,多个线程同时执行业务,并发冲突。
  • 解决:看门狗续期(Redisson),业务没结束就不断延长锁过期时间;不要设置过小锁超时。

4. 主从架构下锁丢失(单机最大坑)

  • 问题:master加锁成功,锁还没异步同步到slave,master宕机,slave晋升为主节点,锁消失,多个客户端获取锁。
  • 解决:
    • 方案1:RedLock红锁(有缺陷,很少线上使用)
    • 方案2:强一致性场景改用Zookeeper/Etcd

5. RedLock自身带来的问题

  1. 时钟漂移、NTP时间跳变,导致锁提前失效
  2. 客户端GC停顿、网络延迟,锁过期,依然会锁失效
  3. 需要维护多套独立Redis节点,性能差、运维成本高

6. 锁不可重入

  • 问题:同一个线程,递归/嵌套再次获取同一个锁,直接加锁失败,造成自己把自己阻塞。
  • 解决:Redisson内部实现可重入锁,记录线程持有计数;自己手写很难实现。

7. 锁等待、死锁(线程A拿锁,线程B无限阻塞)

  • 问题:获取锁失败后,如果无限循环自旋,会大量消耗CPU,压垮Redis。
  • 解决:设置最大等待时间,加退避重试,不要死循环抢锁。

8. 网络抖动问题

  • 问题:Redis已经拿到锁,网络超时,客户端没收到返回;客户端认为加锁失败,实际锁已经存在,资源死锁。
  • 解决:设置合理的网络超时,失败主动释放所有节点残留锁。

总结

手写Redis分布式锁很难做到完备,会踩原子性、误删、锁过期、主从丢锁、不可重入、自旋风暴这些坑;开发中优先直接使用Redisson,不要自己实现。

如果业务对互斥要求极高,不建议用Redis分布式锁。

相关推荐
Sagittarius_A*12 小时前
【好靶场】报错注入-sql注入-数字型
数据库·sql·web安全·sql注入
Wang's Blog12 小时前
Vibe Coding一人即团队系列30: AI辅助数据库脚本设计与字符集问题修复
数据库·人工智能
可乐鸡翅yeah_12 小时前
HTTPS 站点下 M3U8 混合内容问题深度排查,HLS 协议安全策略踩坑实录
数据库·网络协议·https·m3u8·m3u8在线
千里码aicood14 小时前
基于Hadoop的汽车销量分析与可视化
大数据·hadoop·分布式
疯狂打码的少年18 小时前
【数据库技术】关系模型基本概念(关系/属性/元组/键)
java·服务器·数据库·笔记
普马萨特20 小时前
实体与位置关系的数据从哪里来:获取、治理与仍待解决的问题
网络·数据库
醉颜凉20 小时前
MySQL 8 忘记 root 密码?这两种方法帮你轻松解决
数据库·mysql·adb
RestCloud21 小时前
集成链路监控体系搭建:接口调用、数据流转与异常告警全覆盖
数据库·数据安全·ipaas·api管理·数据监控·集成平台·api 治理
xxwl58521 小时前
MySQL 基础学习笔记
数据库·mysql