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分布式锁。

相关推荐
笃行3509 小时前
别拿MySQL数据库管理工具硬导:MySQL 迁 KingbaseES 的完整工具链
数据库
风哥2号9 小时前
数据库教程FGMT51‑PostgreSQL实例管理与参数文件
数据库·postgresql
蓝速科技10 小时前
桌面双屏翻译机量产调试:三类场景兼容性破局方案丨蓝速科技
运维·数据库·人工智能·科技·技术分享
达梦数据10 小时前
DMDRS空间数据类型说明:Oracle、DM8、MySQL空间数据类型映射
数据库·mysql·oracle
白远山10 小时前
24小时自助健身房系统开发实战:从需求分析到完整指南
java·开发语言·数据库·数据挖掘·需求分析
达梦数据11 小时前
DMDRS服务与模块的运行步骤
数据库
让学习成为一种生活方式11 小时前
PMGD:植物线粒体基因组数据库--Journal of Integrative Plant Biology
数据库
zhoupenghui16811 小时前
Redis 集群的安装配置与服务交互
redis·cluster·redis集群
达梦数据12 小时前
达梦数据复制软件DMDRS搭建部署示例:源数据库DM8到目标数据库DM8一对一数据同步
数据库
IT_Octopus12 小时前
从一个应用开发者的角度,搞懂大数据查询的完整链路
java·大数据·数据库