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

相关推荐
smileNicky34 分钟前
SpringBoot系列之集成Pulsar教程
java·spring boot·后端
小翰子_1 小时前
Spring Boot整合Sharding-JDBC实现日志表按月按周分表实战
java·spring boot·后端
踏浪无痕2 小时前
SQLInsight:从JDBC底层到API调用的零侵入SQL监控方案
数据库·后端·开源
superman超哥3 小时前
Rust HashSet与BTreeSet的实现细节:集合类型的底层逻辑
开发语言·后端·rust·编程语言·rust hashset·rust btreeset·集合类型
superman超哥4 小时前
Rust String与&str的内部实现差异:所有权与借用的典型案例
开发语言·后端·rust·rust string·string与str·内部实现·所有权与借用
愈努力俞幸运4 小时前
rust安装
开发语言·后端·rust
踏浪无痕4 小时前
JobFlow 负载感知调度:把任务分给最闲的机器
后端·架构·开源
UrbanJazzerati4 小时前
Python自动化统计工具实战:Python批量分析Salesforce DML操作与错误处理
后端·面试
我爱娃哈哈4 小时前
SpringBoot + Seata + Nacos:分布式事务落地实战,订单-库存一致性全解析
spring boot·分布式·后端
nil5 小时前
记录protoc生成代码将optional改成omitepty问题
后端·go·protobuf