Redisson 是 Redis 官方推荐的 Java 分布式协调组件,它将 Redis 的丰富数据结构扩展为 Java 熟悉的并发对象(如分布式锁、Map、队列、信号量),并提供了完整的集群、哨兵、主从支持。本文将深入剖析 Redisson 的架构基石、分布式锁的完整链路、看门狗机制、异步编程模型以及如何通过 Lua 保证原子性,以“好看懂、能落地”的方式展示其原理。
放一张核心加锁逻辑总图

Redisson 的底层通信完全基于 Netty,所有 Redis 命令执行都是异步非阻塞的,通过 RFuture 抽象将回调转换为 Java 的 CompletionStage 或直接的异步接口。这种设计让它天然支持高吞吐。
整体架构可概括为三个核心支柱:
RMap、RLock、RQueue 等接口,提供本地缓存、监听回调等增强。RLock 是 Redisson 中最广泛使用的特性,其实现远非简单的 SETNX 可比,它要解决可重入、自动续期、非阻塞等待、集群安全四大难题。
加锁的核心是一段精心设计的 Lua 脚本(简化版如下):
-- KEYS[1] 锁名 , ARGV[1] 客户端标识(UUID:线程ID) , ARGV[2] 锁租约时间(ms)
if (redis.call('exists', KEYS[1]) == 0) then
redis.call('hincrby', KEYS[1], ARGV[1], 1);
redis.call('pexpire', KEYS[1], ARGV[2]);
return nil;
end;
if (redis.call('hexists', KEYS[1], ARGV[1]) == 1) then
redis.call('hincrby', KEYS[1], ARGV[1], 1);
redis.call('pexpire', KEYS[1], ARGV[2]);
return nil;
end;
return redis.call('pttl', KEYS[1]);
原理拆解:
客户端UUID:线程ID,值为重入次数。这种方式天然支持了可重入和强一致性——由 Redis 单线程串行化执行脚本。
如果业务执行时间超过锁的租约(30秒),锁会被自动释放,造成并发问题。Redisson 提供了经典的 Watch Dog 机制:
HashedWheelTimer 时间轮),每隔 租约/3 (默认 10 秒)触发一次续期。if (redis.call('hexists', KEYS[1], ARGV[1]) == 1) then
redis.call('pexpire', KEYS[1], ARGV[2]);
return 1;
end;
return 0;
该脚本判断锁是否仍被同一客户端持有,是则将过期时间重置为租约值。解锁同样使用 Lua 脚本保证原子性:
if (redis.call('hexists', KEYS[1], ARGV[1]) == 0) then return nil; end;
local count = redis.call('hincrby', KEYS[1], ARGV[1], -1);
if (count > 0) then
redis.call('pexpire', KEYS[1], ARGV[2]);
return 0;
else
redis.call('del', KEYS[1]);
redis.call('publish', KEYS[2], ARGV[3]); -- 通知等待线程
return 1;
end;
当锁的 Hash 被删除时,Redis 会向频道 redisson_lock__channel:{锁名} 发送 解锁消息,正在 lock() 上阻塞的其他线程会订阅该频道,收到消息后立即竞争锁。这比自旋轮询节省大量网络开销,保障了公平性与低延迟。
在哨兵或集群模式下,Redisson 实现了 RedLock 算法:它会在所有独立的 master 节点上依次尝试获取锁,当在大多数节点(N/2+1)上成功且总耗时不超预算时才算获取成功。这防止了主从切换时的锁丢失,但也以增加复杂度和延迟为代价,适用于极高安全需求的场景。