分布式锁:Redisson、Zookeeper、MySQL 三种方案场景对比&选型参考

面向面试 + 实战双场景,涵盖 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 实现锁 不建议在任何中高并发系统中使用

相关推荐
绝无仅有几秒前
面试真实经历某商银行大厂计算机网络问题和答案总结
后端·面试·github
绝无仅有几秒前
面试真实经历某商银行大厂系统,微服务,分布式问题和答案总结
后端·面试·github
IT_陈寒6 分钟前
5个Java 21新特性实战技巧,让你的代码性能飙升200%!
前端·人工智能·后端
paishishaba34 分钟前
JAVA面试复习笔记(待完善)
java·笔记·后端·面试
Victor3561 小时前
Redis(72)Redis分布式锁的常见使用场景有哪些?
后端
Victor3562 小时前
Redis(73)如何处理Redis分布式锁的死锁问题?
后端
程序员爱钓鱼4 小时前
Python编程实战 · 基础入门篇 | Python的缩进与代码块
后端·python
earthzhang20216 小时前
第3讲:Go垃圾回收机制与性能优化
开发语言·jvm·数据结构·后端·性能优化·golang
thinktik9 小时前
AWS EKS 集成Load Balancer Controller 对外暴露互联网可访问API [AWS 中国宁夏区]
后端·kubernetes·aws
追逐时光者9 小时前
将 EasySQLite 解决方案文件格式从 .sln 升级为更简洁的 .slnx
后端·.net