实现分布式锁

### **1. 数据库实现分布式锁**

#### **核心原理**

1. **基于唯一约束的悲观锁**  

   - 创建一张锁表(如 `distributed_lock`),字段包含锁名称(`lock_key`)和唯一索引。  

   - 客户端尝试插入一条记录(如 `INSERT INTO distributed_lock (lock_key) VALUES ('order_lock')`)。  

   - 若插入成功,表示获取锁;若插入失败(唯一约束冲突),表示锁已被占用。  

 

2. **基于乐观锁(版本号或 CAS)**  

   - 使用版本号字段,更新锁时检查版本号是否匹配:  

     ```sql

     UPDATE distributed_lock SET version = version + 1 

     WHERE lock_key = 'order_lock' AND version = current_version;

     ```

   - 若影响行数大于 0,表示获取锁成功。

 

3. **超时机制**  

   - 为锁记录添加过期时间字段,通过定时任务清理超时锁。

 

#### **优缺点**

- **优点**:  

  - 实现简单,依赖现有数据库,无需额外组件。  

  - 强一致性(基于事务)。  

- **缺点**:  

  - 性能差(频繁的数据库 I/O)。  

  - 死锁风险(客户端崩溃后锁未释放)。  

  - 需额外处理锁超时和续约逻辑。

 

---

 

### **2. Redis 实现分布式锁**

#### **核心原理**

1. **SETNX + EXPIRE(单节点)**  

   - 使用 `SET key value NX PX milliseconds` 命令原子性地设置键值对和过期时间。  

     ```redis

     SET lock:order 12345 NX PX 30000 # 仅当 key 不存在时设置,过期时间 30 秒

     ```

   - 释放锁时通过 Lua 脚本验证值匹配后删除:  

     ```lua

     if redis.call("get", KEYS[1]) == ARGV[1] then

         return redis.call("del", KEYS[1])

     else

         return 0

     end

     ```

 

2. **RedLock 算法(多节点)**  

   - 向多个 Redis 节点(奇数个)依次申请锁,超过半数节点成功且总耗时小于锁超时时间才算成功。  

   - 解决单点故障问题,但实现复杂(需处理时钟漂移、节点崩溃等边界条件)。

 

#### **优缺点**

- **优点**:  

  - 高性能(内存操作,微秒级响应)。  

  - 支持自动过期,避免死锁。  

- **缺点**:  

  - 单节点 Redis 存在脑裂风险(主从切换时锁丢失)。  

  - RedLock 算法争议较大(时钟同步、GC 停顿等问题)。  

  - 最终一致性模型,极端场景可能锁失效。

 

---

 

### **3. ZooKeeper 实现分布式锁**

#### **核心原理**

1. **临时顺序节点(Fair Lock)**  

   - 客户端在锁路径下创建临时顺序节点(如 `/locks/order_lock_00000001`)。  

   - 获取所有子节点,检查自己是否为最小节点。若是,则获得锁;否则监听前一个节点的删除事件。  

 

2. **临时节点(Non-Fair Lock)**  

   - 客户端直接创建临时节点(如 `/locks/order_lock`),若节点已存在则监听其删除事件。  

 

3. **Watch 机制**  

   - 通过 ZooKeeper 的 Watcher 监听节点变化,前序节点释放锁后触发回调,重新尝试获取锁。

 

#### **优缺点**

- **优点**:  

  - 强一致性(基于 ZAB 协议)。  

  - 天然避免死锁(临时节点随会话结束自动删除)。  

  - 公平锁支持(顺序节点)。  

- **缺点**:  

  - 性能较低(需频繁创建节点和触发 Watcher)。  

  - 实现复杂(需处理网络闪断、会话超时等异常)。  

  - 依赖 ZooKeeper 集群的稳定性。

 

---

 

### **对比总结**

| **特性** | **数据库** | **Redis** | **ZooKeeper** |

|-------------------|---------------------------|----------------------------|----------------------------|

| **一致性** | 强一致性(事务) | 最终一致性 | 强一致性(ZAB 协议) |

| **性能** | 低(依赖磁盘 I/O) | 高(内存操作) | 中(网络通信 + 节点操作) |

| **死锁处理** | 需超时机制或人工干预 | 自动过期 | 临时节点自动删除 |

| **实现复杂度** | 简单 | 中等(需处理原子性) | 复杂(需处理 Watcher 机制)|

| **适用场景** | 低并发、强一致性需求 | 高并发、允许短暂不一致 | 高一致性、分布式协调场景 |

 

---

 

### **选择建议**

- **数据库锁**:适合低频操作、强一致性且不想引入新组件的场景。  

- **Redis 锁**:适合高频读写、允许最终一致性的缓存或业务场景(如秒杀)。  

- **ZooKeeper 锁**:适合需要强一致性、高可靠性的分布式协调场景(如金融系统)。  

 

---

 

### **注意事项**

1. **锁续约**:若业务执行时间超过锁超时时间,需实现锁续约逻辑(如 Redis 的 `watchdog`)。  

2. **网络分区**:Redis 可能因脑裂导致锁失效,ZooKeeper 在集群半数存活时仍可用。  

3. **公平性**:ZooKeeper 支持公平锁,Redis 和数据库通常是非公平锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值