Golang Redis如何做分布式锁_Golang Redis分布式锁教程【详解】

加锁必须用 SET key value EX seconds NX,value 需唯一(如 uuid),解锁和续期必须用 Lua 脚本校验 value,TTL 设为业务 P99×2,长任务需看门狗续期,Redlock 多数场景不必要。加锁必须用 SET key value EX seconds NX,别信单 SetNXGo 生态里很多教程说"用 rdb.SetNX 就行",但这是错的------老版本 Redis 不支持在 SetNX 里直接设过期时间,而 Go 客户端(比如 go-redis/v9)的 SetNX(ctx, key, val, ttl) 是靠服务端 SET ... NX EX 命令实现的。如果你连的是 Redis 2.4 或没开 Lua 支持的旧实例,它会 fallback 成两步:先 SETNX,再 EXPIRE,中间一崩溃,锁就永远卡住。value 必须是每个 goroutine 独立生成的,比如 uuid.NewString();写死成 "1" 或复用字符串,解锁时根本分不清是谁的锁EX 足够,除非你要毫秒级精度(那就用 PX);但注意 Go 的 time.Second 别误转成纳秒传给 EX,否则锁 1 秒变 10 亿秒TTL 建议设为「业务 P99 耗时 × 2」,比如导出接口最长跑 1.2s,就设 2 * time.Second;太短会导致锁提前释放,太长会让故障恢复变慢解锁必须用 Lua 脚本,GET + DEL 是经典竞态很多人写完 GET 判断值相等,再调 DEL,结果 A 拿着锁还没删,B 查到过期去抢,A 一删就把 B 刚 set 的锁干掉了------这不是 bug,是必然发生的 race condition。唯一安全解法是原子脚本:EVAL "if redis.call('get', KEYS1) == ARGV1 then return redis.call('del', KEYS1) else return 0 end" 1 lock:key abc123Go 里用 redis.NewScript(unlockScript).Run(ctx, rdb, \[\]string{key}, clientID),返回 int64,非 1 就代表解锁失败,得记录日志或告警别把脚本拼在代码里,用 embed.FS 或 const 管理,方便审计和灰度上线时热替换长任务必须配看门狗续期,EXPIRE 单独调等于裸奔业务执行时间不确定,锁又不能不设 TTL(否则主从切换后锁丢失),这矛盾只能靠续期解。但乱续期更危险:A 续了 B 的锁,B 还以为自己拿着锁在改数据。续期也得用 Lua 校验:if redis.call("GET", KEYS1) == ARGV1 then return redis.call("EXPIRE", KEYS1, ARGV2) else return 0 end续期间隔建议为 TTL / 3,比如 TTL=2s,就每 600ms 续一次;太密增加 Redis 压力,太疏容易掉锁业务函数 return 前必须显式 stop 续期 goroutine,否则锁释放了,后台还在不停续------变成"幽灵续期"Redlock 不是银弹,多数场景单实例+正确实现就够用Redlock 看起来高大上,但实际落地要连 ≥3 个独立 Redis 实例、校准时钟、处理网络分区、应对幽灵锁......运维成本远超收益。除非你有金融级一致性要求,否则单实例锁只要做到 value 唯一 + Lua 解锁 + 合理 TTL + 续期,已覆盖订单幂等、库存扣减、定时任务防重跑等绝大多数场景。 幻导航网 发现优质实用网站,开启网络探索之旅!

相关推荐
顾林海4 小时前
Agent入门阶段-编程基础-Python:流程控制
python·agent·ai编程
呱呱复呱呱6 小时前
Django CBV 源码解读:一个请求是怎么找到你的 get() 方法的
python·django
Nturmoils7 小时前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
曲幽11 小时前
刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API
python·fastapi·web·translate·goldendict·libretranslate·stardict·pystardict
渣波11 小时前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
荣码11 小时前
用Streamlit给AI应用套个界面,10行代码出Web页面
java·python
兵慌码乱21 小时前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·sqlite·信号与槽·pyqt5·数据库设计·桌面应用开发·事务处理
金銀銅鐵1 天前
[Python] 体验用欧几里得算法计算最大公约数的过程
python·数学
FreakStudio1 天前
W55MH32L-EVB 上手测评:硬件 TCP/IP 加持的以太网单片机,MicroPython 零门槛开发
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
用户0332126663671 天前
使用 Python 从零创建 Word 文档
python