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', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) 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", KEYS[1]) == ARGV[1] then return redis.call("EXPIRE", KEYS[1], ARGV[2]) else return 0 end续期间隔建议为 TTL / 3,比如 TTL=2s,就每 600ms 续一次;太密增加 Redis 压力,太疏容易掉锁业务函数 return 前必须显式 stop 续期 goroutine,否则锁释放了,后台还在不停续------变成"幽灵续期"Redlock 不是银弹,多数场景单实例+正确实现就够用Redlock 看起来高大上,但实际落地要连 ≥3 个独立 Redis 实例、校准时钟、处理网络分区、应对幽灵锁......运维成本远超收益。除非你有金融级一致性要求,否则单实例锁只要做到 value 唯一 + Lua 解锁 + 合理 TTL + 续期,已覆盖订单幂等、库存扣减、定时任务防重跑等绝大多数场景。 幻导航网 发现优质实用网站,开启网络探索之旅!

相关推荐
HappyAcmen7 分钟前
2.lcut返回列表用法
python
Json____11 分钟前
Python练习题集-文件处理、数据管理与网络编程实战小项目15个
python·编程·编程学习·练习题·python学习
星空椰18 分钟前
Python 使用飞书 API 获取部门直属用户列表(递归获取所有部门 + 导出 Excel)
python·飞书
l1t21 分钟前
在aarch64机器上安装clang来生成codonjit python模块
开发语言·python
辰尘_星启35 分钟前
【Linux】Python Socket编程指南
linux·python·socket·系统·通信
南宫萧幕44 分钟前
基于 Simulink 与 Python 联合仿真的 eVTOL 强化学习全链路实战
开发语言·人工智能·python·算法·机器学习·控制
电魂泡哥1 小时前
CMS垃圾回收
java·jvm·算法
Amctwd1 小时前
【Python】从Excel中按行提取图片
java·python·excel
环流_1 小时前
Redis中string类型的应用场景
数据库·redis·缓存
倔强的石头_1 小时前
拒绝被复杂报表拖垮!HTAP场景下“标量子查询消除”硬核调优指南
数据库