分布式锁: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 实现锁 不建议在任何中高并发系统中使用

相关推荐
Victor35617 小时前
Netty(20)如何实现基于Netty的WebSocket服务器?
后端
缘不易17 小时前
Springboot 整合JustAuth实现gitee授权登录
spring boot·后端·gitee
Kiri霧17 小时前
Range循环和切片
前端·后端·学习·golang
WizLC17 小时前
【Java】各种IO流知识详解
java·开发语言·后端·spring·intellij idea
Victor35617 小时前
Netty(19)Netty的性能优化手段有哪些?
后端
爬山算法17 小时前
Netty(15)Netty的线程模型是什么?它有哪些线程池类型?
java·后端
白宇横流学长18 小时前
基于SpringBoot实现的冬奥会科普平台设计与实现【源码+文档】
java·spring boot·后端
Python编程学习圈18 小时前
Asciinema - 终端日志记录神器,开发者的福音
后端
bing.shao19 小时前
Golang 高并发秒杀系统踩坑
开发语言·后端·golang
壹方秘境19 小时前
一款方便Java开发者在IDEA中抓包分析调试接口的插件
后端