setnx为什么不是高可用的分布式锁实现
15 分钟阅读
•
928 字
+
1811 词
1. 基于 Redis 的分布式锁
方案
-
单节点 Redis
:使用
SET key value NX PX timeout命令实现锁的互斥性和自动超时释放。 - RedLock 算法 :在多个独立 Redis 节点上同时申请锁,半数以上节点成功时视为获取锁,避免单点故障。
优点
- 性能高,适用于高并发场景。
- RedLock 通过多节点部署提升可用性。
缺点
- RedLock 存在争议(如时钟漂移、GC 停顿可能导致锁失效)。
- 单节点 Redis 存在单点故障风险。
工具
- Redisson (Java 客户端实现 RedLock)。
2. 基于 ZooKeeper 的分布式锁
方案
-
利用
临时顺序节点(Ephemeral Sequential Nodes)
实现锁:
- 客户端在锁路径下创建临时顺序节点。
- 判断自己是否为最小序号节点,若是则获取锁。
- 非最小节点监听前序节点的删除事件( Watcher 机制 )。
优点
- 强一致性保障,避免锁冲突。
- 临时节点自动删除,防止死锁。
- 适合对一致性要求高的场景。
缺点
- 写性能低于 Redis。
- 频繁的 Watcher 通知可能带来性能开销。
工具
- Curator (ZooKeeper 客户端库,提供现成的锁实现)。
3. 基于 etcd 的分布式锁
方案
-
利用 etcd 的
Lease(租约)
和
Revision
机制:
- 客户端创建带 Lease 的键值对(Lease 自动过期)。
- 通过事务(Transaction)比较 Revision 号,确保锁的互斥性。
优点
- 基于 Raft 协议,强一致性高可用。
- Lease 机制自动释放锁,避免死锁。
缺点
- 性能略低于 Redis,但高于 ZooKeeper。
工具
- etcd 官方客户端库(如 etcdv3 )。
4. 基于数据库的分布式锁
方案
- 唯一索引/乐观锁 :通过数据库的唯一约束或版本号实现锁竞争。
- 专用表结构 :例如记录锁名称、持有者、超时时间等字段。
优点
- 实现简单,无需额外组件。
缺点
- 性能差(数据库连接开销大)。
- 需处理锁超时和死锁问题。
- 高可用依赖数据库主从同步(可能引入延迟)。
5. 基于 Consul 的分布式锁
方案
-
利用
Session 机制
:
- 创建 Session 并与键关联。
- Session 失效时自动释放锁。
优点
- 内置服务发现和健康检查,适合微服务架构。
- 支持 ACL 增强安全性。
缺点
- 性能低于 Redis 和 etcd。
6. 云厂商托管服务
- AWS DynamoDB Lock Client :基于 DynamoDB 的托管锁服务。
- 阿里云 Distributed Lock :集成于阿里云产品中。
- Google Cloud Memorystore (Redis) :托管 Redis 服务实现锁。
优点
- 免运维,高可用性由云厂商保障。
- 开箱即用。
缺点
- 绑定特定云环境,可能产生成本。
选择建议
- 强一致性场景 :选 ZooKeeper 或 etcd。
- 高性能场景 :选 Redis(需评估 RedLock 风险)。
- 云原生环境 :优先使用托管服务(如 AWS/Aliyun)。
- 简单场景 :数据库锁(适用于低频访问)。
注意事项
- 锁自动释放 :通过超时机制(TTL)避免死锁。
- 可重入性 :需记录锁持有者(如线程/进程 ID)及重入次数。
- 公平性 :ZooKeeper 的临时顺序节点天然支持公平锁。
- 网络分区(脑裂) :需结合业务容忍度选择 CP 或 AP 模型。
以上方案各有优劣,需结合业务场景的 一致性需求 、 性能要求 和 运维成本 综合选择。