分布式并发

分布式锁和一致性算法是分布式系统中解决并发问题的核心技术,也是面试必考内容。

分布式锁概述 ⭐⭐⭐⭐⭐

为什么需要分布式锁

单机锁的局限

// 单机环境:synchronized 有效
public synchronized void deductStock() {
    if (stock > 0) {
        stock--;
    }
}

// 分布式环境:多个 JVM,synchronized 失效
// 服务器1:stock=1,扣减成功
// 服务器2:stock=1,同时扣减成功
// 结果:超卖!

分布式锁的场景

  • 库存扣减(防止超卖)

  • 订单号生成(防止重复)

  • 定时任务(防止重复执行)

  • 缓存重建(防止缓存击穿)

分布式锁的要求

要求
说明

互斥性

同一时刻只有一个客户端持有锁

安全性

不会死锁,即使客户端崩溃

容错性

只要多数节点存活,就能加锁/解锁

唯一性

加锁和解锁必须是同一个客户端


Redis 分布式锁 ⭐⭐⭐⭐⭐

基础实现(SETNX)

错误版本 1:SETNX + EXPIRE 分两步

错误版本 2:SET NX EX 但不校验身份

正确实现

1. 加锁

2. 解锁(Lua 脚本保证原子性)

存在的问题

1. 锁超时问题

解决方案:Redisson 看门狗

2. 主从复制延迟

解决方案:RedLock 算法(后文)

Redisson 实现

基本使用

看门狗机制

RedLock 算法

原理:向多个独立的 Redis 实例加锁,多数成功则认为加锁成功。

流程

Redisson 实现

优缺点

  • ✅ 解决主从复制延迟问题

  • ❌ 需要多个独立 Redis 实例

  • ❌ 性能开销大


Zookeeper 分布式锁 ⭐⭐⭐⭐⭐

实现原理

基于临时顺序节点

手动实现

Curator 实现

基本使用

读写锁

ZK vs Redis 锁对比

特性
Redis
Zookeeper

性能

高(内存)

中(磁盘 + 网络)

可靠性

中(可能丢锁)

高(CP 模型)

实现复杂度

高(需处理超时、续期)

低(框架封装)

死锁

可能(超时未处理)

不会(临时节点)

公平性

不公平

公平(顺序节点)

适用场景

高性能、允许偶尔失败

强一致性、不能失败


一致性算法概述 ⭐⭐⭐⭐

Raft 算法

核心概念

1. 角色

  • Leader:处理所有客户端请求

  • Follower:被动接收请求,转发给 Leader

  • Candidate:选举时的临时角色

2. 选举流程

3. 日志复制

特点

  • 强一致性

  • 易于理解和实现

  • 应用:etcd、Consul

Paxos 算法

核心概念

1. 角色

  • Proposer:提议者

  • Acceptor:接受者

  • Learner:学习者

2. 两阶段提交

Phase 1(准备阶段)

Phase 2(接受阶段)

特点

  • 理论基础

  • 实现复杂

  • 应用:Google Chubby、Zookeeper(ZAB 协议,Paxos 变种)

Raft vs Paxos

特性
Raft
Paxos

易理解性

实现复杂度

性能

相当

相当

应用

etcd、Consul

Chubby、ZK


分布式锁最佳实践 ⭐⭐⭐⭐⭐

选型建议

Redis 适用场景

  • 高性能要求

  • 允许偶尔失败(如计数统计)

  • 对可靠性要求不极致

Zookeeper 适用场景

  • 强一致性要求

  • 不能丢锁(如扣款、库存)

  • 需要公平锁

实战案例:秒杀库存扣减

方案 1:Redis 锁 + Lua 脚本

方案 2:Zookeeper 锁 + MySQL


面试要点 ⭐⭐⭐⭐⭐

Q1: 分布式锁有哪些实现方式?

  • Redis:基于 SETNX 和 Lua 脚本

  • Zookeeper:基于临时顺序节点

  • 数据库:基于唯一索引或行锁

Q2: Redis 分布式锁的正确实现?

Q3: Redis 锁有什么问题?

  • 锁超时:业务执行时间超过锁过期时间

  • 主从复制延迟:主节点宕机,锁未同步到从节点

Q4: 什么是 Redisson 看门狗?

  • 自动续期机制

  • 默认 30s 锁,每 10s 续期一次

  • unlock() 时停止续期

Q5: 什么是 RedLock?

  • 向多个独立 Redis 实例加锁

  • 多数成功则认为加锁成功

  • 解决主从复制延迟问题

Q6: Zookeeper 锁的实现原理?

  • 创建临时顺序节点

  • 最小节点获得锁

  • 监听前一个节点,等待删除

Q7: Redis 锁和 ZK 锁的区别?

  • Redis:高性能,可能丢锁,不公平

  • Zookeeper:强一致,不会丢锁,公平

Q8: Raft 和 Paxos 的区别?

  • Raft:易理解,实现简单

  • Paxos:理论基础,实现复杂

  • 性能相当


参考资料

  1. 书籍推荐:《分布式系统原理与实践》、《从 Paxos 到 Zookeeper》

  2. 论文

    • 《In Search of an Understandable Consensus Algorithm (Raft)》

    • 《The Part-Time Parliament (Paxos)》

  3. 开源项目:Redisson、Curator

Last updated