redlock要求至少3个独立redis实例,因其安全模型依赖多数派机制:加锁必须在≥n/2+1个节点(如3节点需2个、5节点需3个)上成功,且总耗时小于锁过期时间,才能容忍最多⌊(n−1)/2⌋个节点故障,确保容错性与互斥性。

Redlock 不是银弹,它只在多数节点可用、网络延迟可控、业务允许少量不一致时才真正可靠。直接用 SETNX + Lua 解锁是最常用且够用的方案;Redlock 仅当你的场景明确要求“避免 Redis 主从切换导致的锁失效”时才值得引入。
为什么 Redlock 要求至少 3 个独立 Redis 实例
Redlock 的安全模型依赖“多数派”:加锁必须在 ≥ N/2+1 个节点上成功,且总耗时 redis-go 客户端连接的每个 redis.Client 必须指向物理隔离的实例(不能是同一集群的主从副本),否则起不到容错作用。
redlock-go 加锁时最关键的三个参数
-
ttl:锁有效期,必须明显大于业务执行时间(建议 ≥ 1.5 倍),但不能过长(否则故障后释放慢) -
retryTimes:重试次数,Redlock 内部会尝试在每个节点上反复获取锁,设为 0 表示不重试,设为 3 是较稳妥的选择 -
retryDelay:每次重试前等待时间,单位毫秒,设为100可缓解瞬时网络抖动
示例调用:
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
dl := redlock.New(redlock.Options{
Endpoints: []string{"redis://192.168.1.10:6379", "redis://192.168.1.11:6379", "redis://192.168.1.12:6379"},
})
lock, err := dl.Lock("order:12345", 5*time.Second)注意:Lock 返回的是 *redlock.Lock,不是布尔值;失败时 err != nil,不要忽略。
解锁必须用 defer 且带 context 超时
Redlock 的解锁不是简单 del key,而是向所有参与加锁的节点广播释放请求。如果某节点不可达,Unlock() 会阻塞直到超时——这会导致 goroutine 泄漏。正确做法是:
- 加锁后立即用
defer lock.Unlock() - 但更保险的是包裹一层带 timeout 的 context:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() lock.Unlock(ctx)
- 不要在业务逻辑里手动调用
Unlock(),尤其不要在 error 分支里重复调用——redlock-go的Unlock是幂等的,但重复调用仍会浪费网络请求
Redlock 最容易被忽略的两个现实问题
第一,时钟漂移。Redlock 假设各 Redis 节点系统时间误差
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










