Redis3主3从时怎么用分布式锁
在 Redis 3主3从集群中实现分布式锁时,需结合 Redis Cluster 的特性和分布式锁的核心原则(互斥性、容错性、避免死锁)设计。以下是具体方案及注意事项:
# 🔒 一、基础方案:单节点锁(适用于低要求场景)
# 实现步骤
加锁命令
使用SET key unique_value NX PX 30000
命令:NX
:仅当 Key 不存在时设置,保证互斥性。PX 30000
:设置 30 秒超时,避免死锁。unique_value
:使用 UUID 或线程 ID 标识锁持有者。
释放锁
通过 Lua 脚本原子化释放(避免误删其他客户端的锁):if redis.call("GET", KEYS[1]) == ARGV[1] then return redis.call("DEL", KEYS[1]) else return 0 end
1
2
3
4
5
# 风险
- 主从切换导致锁丢失
主节点加锁后数据未同步到从节点时,若主节点宕机,从节点升级后无锁数据,导致其他客户端可重复加锁。 - 锁续期问题
业务执行超时需手动续期(Watch Dog 机制),否则锁自动失效。
适用场景:对锁可靠性要求不高的业务(如缓存更新)。
# ⚙️ 二、高可用方案:RedLock 算法(官方推荐)
针对主从容错问题,Redis 作者提出 RedLock 算法,通过多节点投票机制提升可靠性。
# 实现流程
部署独立节点
3主3从集群中,将 3个主节点视为独立节点(从节点仅用于备份,不参与锁决策)。加锁步骤:
- 生成全局唯一 ID(如 UUID)作为锁标识。
- 向所有主节点顺序发送加锁命令(
SET key uuid NX PX TTL
),并记录操作开始时间T1
。 - 计算总耗时
T_total = T2 - T1
(T2
为收到最后一个响应的时间),需满足:T_total < 锁超时时间
(防止锁自动失效)。- 成功节点数 ≥ N/2 + 1(3节点时需至少2个成功)。
- 若成功,锁实际有效时间 =
TTL - T_total - 时钟漂移补偿
。
释放锁:
向所有主节点发送 Lua 脚本释放锁(即使未成功加锁的节点也需尝试)。
# 参数配置
参数 | 建议值 | 说明 |
---|---|---|
锁超时时间(TTL) | 10s-30s | 需大于业务最大耗时 |
重试间隔 | 100-300ms | 避免频繁重试压垮节点 |
续期间隔 | TTL/3(如10s) | Watch Dog 续期频率 |
# 生产级工具
推荐使用 Redisson 库(支持自动续期、可重入锁、RedLock 封装):
RedissonClient client = Redisson.create();
RLock lock1 = client.getLock("lock1");
RLock lock2 = client.getLock("lock2");
RLock lock3 = client.getLock("lock3");
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
try {
if (redLock.tryLock(5, 30, TimeUnit.SECONDS)) { // 尝试5秒,锁有效期30秒
// 执行业务逻辑
}
} finally {
redLock.unlock();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# ⚠️ 三、关键注意事项
时钟同步问题
节点间时钟漂移可能导致锁提前失效。建议通过 NTP 协议同步时间。GC 停顿风险
客户端长时间 GC 可能导致锁过期后误操作资源。需设置合理的 TTL 并监控 GC 时间。节点故障恢复
节点崩溃后若未持久化锁数据,恢复后可能与其他节点状态冲突。建议开启 AOF 持久化。性能与可靠性权衡
- 单节点锁:性能高,但可靠性低(仅用于非关键任务)。
- RedLock:可靠性高,但多节点通信增加延迟(适合金融等高要求场景)。
锁粒度控制
锁 Key 需精确到业务资源(如order_123
),避免全局锁竞争。
# 💎 四、生产环境推荐方案
场景 | 方案 | 工具 |
---|---|---|
非关键任务(如缓存更新) | 单节点锁 + Lua 释放 | Spring Data Redis |
高并发业务(如订单支付) | RedLock 多节点投票 | Redisson 库 |
强一致性要求(如库存扣减) | 结合数据库事务 + Redis 锁兜底 | Seata + Redisson |
注:Redis Cluster 的 3主3从架构中,RedLock 只需操作 3 个主节点(N=3),满足 N/2 + 1 = 2 的成功条件即可。
# 📚 五、扩展阅读:RedLock 的争议与替代
- 争议点:极端场景下(如网络分区 + GC 停顿)仍可能锁失效。
- 替代方案:
- ZooKeeper 锁:基于 ZAB 协议强一致,但性能低于 Redis。
- etcd 锁:基于 Raft 协议,适合对一致性要求极高的场景。
建议根据业务容忍度选择方案:Redis 锁适用于 AP 系统(高可用优先),ZK/etcd 适用于 CP 系统(强一致优先)。
编辑 (opens new window)
上次更新: 2025/06/24, 00:41:57