面向面试 + 实战双场景,涵盖 API 用法、源码原理、性能差异、踩坑经验,一文带你读透分布式锁的核心知识体系。
🧩 一、分布式锁的设计目标
分布式环境中,一个合格的锁需要满足以下核心特性:
- 互斥性:同一时刻只能有一个客户端持有锁
- 可重入性:同一线程可以重复获得锁
- 安全释放:避免释放掉别人的锁
- 容错性:服务宕机后锁可自动释放
- 高可用性:不能成为系统瓶颈
- 高性能:延迟低、并发强
🧱 二、主流实现方案对比
实现方式 | 优势 | 缺点 | 是否推荐 |
---|---|---|---|
Redis(Redisson) | 高性能、支持多种锁、自动续约、API 丰富 | Redis 单点风险(需哨兵或集群)、依赖内存 | ✅ 推荐 |
Zookeeper | 强一致性、顺序临时节点、天然支持公平锁 | TPS 较低、维护复杂 | ⚠️ 谨慎 |
MySQL | 易于上手、可用性高 | 实现复杂、易死锁、性能差、不可自动释放 | ❌ 不推荐 |
🚀 三、Redisson 分布式锁实战
✅ 1. 基本使用
java
RLock lock = redissonClient.getLock("order:lock:" + orderId);
lock.lock(10, TimeUnit.SECONDS); // 最多持有 10 秒
try {
// 执行业务逻辑
} finally {
lock.unlock();
}
🧠 2. 看门狗机制详解
- 默认加锁时间为 30 秒
- Redisson 会在后台自动续期(每隔 10 秒续 30 秒)
- 适用于业务执行时间不确定的场景
🔒 3. 锁释放的原子性(Lua 脚本)
使用 Lua 保证"判断是否自己持有锁 + 删除锁"原子执行:
lua
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
🧾 4. 注解式封装(简化调用)
java
@RedisLock(key = "order:lock:#orderId", expire = 20)
public void createOrder(Long orderId) {
// your business logic
}
🦁 四、Zookeeper 分布式锁原理
✨ 原理简介
- 客户端在
/lock
节点下创建临时顺序节点,如/lock/lock_0000001
- 所有客户端监听比自己小的前一个节点
- 最小编号者获得锁,释放后触发下一个客户端监听器
🧪 示例(Curator)
java
InterProcessMutex lock = new InterProcessMutex(client, "/lock/order");
lock.acquire();
try {
// 临界区
} finally {
lock.release();
}
🧱 五、MySQL 锁实现方式(仅学习用途)
🏗️ 方式一:唯一主键锁表法
sql
CREATE TABLE distributed_lock (
lock_key VARCHAR(64) PRIMARY KEY,
expire_at DATETIME
);
sql
-- 加锁
INSERT INTO distributed_lock(lock_key, expire_at)
VALUES ('order_lock', now() + interval 30 second);
-- 解锁
DELETE FROM distributed_lock WHERE lock_key = 'order_lock';
🚨 问题
- 表锁性能差,不适合高并发
- 不具备自动过期能力
- 事务控制复杂,易产生死锁
📚 六、典型应用场景
🎯 幂等控制(避免重复下单)
java
RLock lock = redissonClient.getLock("order:lock:" + userId);
if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {
try {
// 幂等校验逻辑
} finally {
lock.unlock();
}
}
🛡️ 缓存击穿保护
- 热点数据突然失效,防止多个线程同时访问 DB
- 可结合 Bloom Filter + 分布式锁
⏳ 限流控制(加锁 + 队列)
- 通过锁粒度控制同时执行的任务数量
- 可用于控制某些业务压测/大促期间限流策略
📈 七、性能 & 适用场景对比
实现方案 | 性能 | 一致性保障 | 开发成本 | 适用场景 |
---|---|---|---|---|
Redis | ⭐⭐⭐⭐ | 弱一致性 | 低 | 秒杀、缓存更新、幂等控制 |
Zookeeper | ⭐⭐ | 强一致性 | 中 | 任务调度、公平锁 |
MySQL | ⭐ | 基于事务 | 低 | 小并发系统或实验环境 |
❓ 八、常见面试问答速记
🔹 Q:Redisson 和原生 Redis 加锁有何不同?
Redisson 内部封装了看门狗机制、Lua 原子解锁、支持公平锁/联锁/红锁等高级特性,避免自己维护续约线程、并发细节。
🔹 Q:为什么不推荐用 MySQL 实现分布式锁?
MySQL 作为关系型数据库,不适合高频并发场景,表锁实现复杂、缺乏原子释放机制,且无自动超时释放能力,极易出现死锁。
🔹 Q:Zookeeper 为什么可以实现公平锁?
其基于"顺序临时节点"机制,所有客户端排队监听比自己序号小的节点,天然具备公平性。
✅ 总结
- ✅ 推荐使用 Redisson:性能高、易用、可扩展,适配大多数 Spring Boot 项目
- ⚠️ Zookeeper 适用于对一致性极高要求的任务调度、主节点竞选等场景
- ❌ MySQL 实现锁 不建议在任何中高并发系统中使用