我们来说一说 Redisson 的原理

简介: 我是小假 期待与你的下一次相遇 ~

前言

Redisson 不仅仅是一个 Redis 客户端,它更是一个在 Redis 基础上实现的 Java 驻内存数据网格(In-Memory Data Grid)。它的核心目标是让 Java 开发者能够以最自然的方式使用 Redis,将复杂的 Redis 命令封装成大家熟悉的 Java 接口(如 java.util.concurrent 包下的接口)。

一、核心设计理念

Redisson 的原理可以概括为:通过 Netty 实现高性能、非阻塞的通信,将 Redis 的数据结构映射为 Java 对象和分布式对象,并在此基础上,利用 Redis 的单线程原子性特性,实现了一系列分布式的、线程安全的 Java 常用工具。

二、核心架构与通信层

1. 基于 Netty 的异步非阻塞通信

  • Netty 框架:Redisson 使用 Netty 4+ 作为其网络通信框架。这保证了高吞吐量和低延迟的连接管理。它允许同时处理成千上万的连接,而不会为每个连接创建单独的线程。
  • 连接管理:Redisson 维护着一个与 Redis 服务器的连接池(可以是单机、哨兵、集群等模式)。它通过 ConnectionManager 来统一管理这些连接的生命周期、心跳检测、重连机制等。
  • 异步与响应式:所有操作在底层都是异步的。当你调用 get("key") 时,Redisson 会通过 Netty 将一个请求写入 Channel,然后立即返回一个 RFuture 对象。你可以同步等待这个 Future(future.get()),也可以为其添加监听器进行异步回调。这为构建高并发应用打下了基础。

2. 编解码器

  • Redisson 使用可插拔的编解码器来序列化/反序列化 Java 对象和 Redis 存储的二进制数据。
  • 默认使用 JacksonJsonCodec,但你也可以选择 StringCodecAvroCodec 等,或者自定义。这保证了存储格式的灵活性。

三、关键原理详解:如何实现分布式对象与服务

这是 Redisson 最核心、最巧妙的部分。它不仅仅是发送命令,而是在 Redis 的数据结构上构建了一层对象逻辑

1. 分布式对象

Redisson 将 Redis 的每一种基本数据结构都包装成了一个 Java 对象。

  • RList: 对应 Redis 的 List。当你调用 RList.add(object) 时,Redisson 底层会执行 RPUSH 命令。RList 实现了 java.util.List 接口,所以你感觉像是在操作本地集合。
  • RMap: 对应 Redis 的 Hash。实现了 java.util.Map 接口。底层使用 HMSET, HGETALL 等命令。
  • RSortedSet: 对应 Redis 的 Sorted Set。实现了 java.util.SortedSet 接口。

原理:这些对象内部持有一个 CommandAsyncExecutor。你的每一个方法调用(如 map.put(key, value)),都会被转换成一个或多个 Redis 命令,并通过 Netty 发送给 Redis 服务器。

2. 分布式集合

这是对分布式对象的扩展,增加了本地缓存功能。例如 RListCache RMapCache

  • 原理:它们不仅将数据存储在 Redis 中,还会在 JVM 本地内存中缓存一份。它们通过监听 Redis 的发布订阅(Pub/Sub) 频道来保证集群中所有节点的本地缓存一致性。当任何一个节点修改了数据,它会发布一个消息,其他节点收到后,会使自己本地的对应缓存失效。

3. 分布式锁 - 核心亮点

这是 Redisson 最著名的功能。它实现了 java.util.concurrent.locks.Lock 接口。

原理图如下:

加锁原理(lock() 方法):

  1. 唯一值: 每个锁请求都会有一个唯一的 UUID + 线程 ID 作为值。这用于标识锁的持有者,避免其他客户端释放了不属于自己的锁。
  2. Lua 脚本: 加锁操作是通过执行一段 Lua 脚本完成的。Lua 脚本在 Redis 中执行是原子性的,这是实现锁的关键。
-- KEYS[1] 是锁的key,ARGV[1] 是锁的过期时间,ARGV[2] 是唯一值
if (redis.call('exists', KEYS[1]) == 0) then
    -- 锁不存在,则加锁
    redis.call('hset', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    return nil;
end;
-- 锁已存在,检查是否是当前线程持有的
if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then
    -- 是当前线程,重入次数+1
    redis.call('hincrby', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    return nil;
end;
-- 锁被其他线程占用,返回锁的剩余生存时间
return redis.call('pttl', KEYS[1]);
  1. 看门狗(Watchdog)机制: 如果客户端没有显式指定锁的超时时间,Redisson 会启动一个看门狗线程。它会在锁过期时间的三分之一左右时,不断延长锁的持有时间(通过 pexpire 命令)。只要 JVM 没有挂掉,这个锁就不会因为超时而被意外释放,从而避免了死锁。如果 JVM 挂掉,看门狗线程也随之停止,锁最终会自动过期。

解锁原理(unlock() 方法):

  1. Lua 脚本: 同样通过 Lua 脚本保证原子性。
-- KEYS[1] 是锁的key,ARGV[1] 是唯一值
if (redis.call('hexists', KEYS[1], ARGV[1]) == 0) then
    return nil;
end;
-- 重入次数-1
local counter = redis.call('hincrby', KEYS[1], ARGV[1], -1);
if (counter > 0) then
    -- 如果重入次数还大于0,则重新设置过期时间
    redis.call('pexpire', KEYS[1], 30000);
    return 0;
else
    -- 重入次数为0,删除key
    redis.call('del', KEYS[1]);
    -- 发布一条解锁消息,通知其他等待的客户端
    redis.call('publish', KEYS[2], ARGV[2]);
    return 1;
end;
return nil;

等待锁的原理: 如果获取锁失败,客户端并不会不停地轮询,而是通过 Redis 的发布订阅(Pub/Sub) 功能,订阅一个特定的频道。当锁被释放时,当前持有锁的客户端会发布一个消息(见上面解锁脚本的最后),所有等待的客户端都会收到通知,然后竞争性地再次尝试加锁。这大大减少了不必要的网络请求。

4. 其他同步器(如 RSemaphore, RCountDownLatch

原理与锁类似,都是基于 Redis 的原子性操作(Lua 脚本)和发布订阅机制。

  • RSemaphore: 使用 Redis 的字符串结构存储许可数量。acquire() 减少数量,release() 增加数量。如果没有许可,则通过发布订阅等待。
  • RCountDownLatch: 使用 Redis 的字符串结构存储计数。countDown() 递减计数,await() 等待计数变为0。当计数为0时,通过发布订阅通知所有等待的线程。

四、数据分片与集群支持

Redisson 能够无缝地与 Redis 集群配合工作。

  • 自动重定向: 当在集群模式下执行一个命令时,如果返回 -MOVED 错误,Redisson 的 ClusterConnectionManager 会自动更新其 Slot-Node 映射表,并将命令重新路由到正确的节点。
  • Pipelining: 支持在集群模式下将多个命令打包成一个 pipeline 发送,以提高性能。

五、总结:Redisson 的核心原理

  1. 网络与通信: 基于 Netty 的高性能、异步、非阻塞通信模型。
  2. 原子性基石: 充分利用 Lua 脚本 在 Redis 中执行的原子性,来实现复杂的分布式同步逻辑。
  3. 事件驱动: 广泛使用 发布订阅(Pub/Sub) 机制来实现事件通知,避免低效的轮询,如锁的等待、缓存失效等。
  4. 对象映射: 将 Redis 的数据结构通过编解码器映射为熟悉的 Java 对象接口(List, Map, Lock 等)。
  5. 容错与高可用: 通过看门狗机制、连接池管理、重连机制、哨兵和集群模式的支持,保证了服务的鲁棒性。

简单来说,Redisson 的原理就是 “用 Redis 的命令做砖瓦,用 Lua 脚本做水泥,用 Netty 做骨架,为 Java 世界构建了一座名为 ‘分布式工具’ 的大厦”。它让你在分布式环境中,获得了近乎与单机应用相同的编程体验。

相关文章
|
8月前
|
存储 缓存 NoSQL
【📕分布式锁通关指南 12】源码剖析redisson如何利用Redis数据结构实现Semaphore和CountDownLatch
本文解析 Redisson 如何通过 Redis 实现分布式信号量(RSemaphore)与倒数闩(RCountDownLatch),利用 Lua 脚本与原子操作保障分布式环境下的同步控制,帮助开发者更好地理解其原理与应用。
576 6
|
8月前
|
前端开发 测试技术 API
Playwright与PyTest结合使用指南
Playwright与PyTest强强联合,打造高效Web自动化测试方案。前者提供现代化跨浏览器自动化能力,后者带来结构化测试管理与强大扩展性。本文详解二者集成:从环境安装、用例编写、配置执行,到高级技巧如Fixture深度使用、并行测试、页面对象模式及移动端模拟,助你快速构建稳定、可维护的自动化测试体系。
Playwright与PyTest结合使用指南
|
7月前
|
人工智能 安全 中间件
阿里云 AI 中间件重磅发布,打通 AI 应用落地“最后一公里”
9 月 26 日,2025 云栖大会 AI 中间件:AI 时代的中间件技术演进与创新实践论坛上,阿里云智能集团资深技术专家林清山发表主题演讲《未来已来:下一代 AI 中间件重磅发布,解锁 AI 应用架构新范式》,重磅发布阿里云 AI 中间件,提供面向分布式多 Agent 架构的基座,包括:AgentScope-Java(兼容 Spring AI Alibaba 生态),AI MQ(基于Apache RocketMQ 的 AI 能力升级),AI 网关 Higress,AI 注册与配置中心 Nacos,以及覆盖模型与算力的 AI 可观测体系。
1437 70
|
6月前
|
人工智能 运维 Serverless
函数计算 × MSE Nacos : 轻松托管你的 MCP Server
本文将通过一个具体案例,演示如何基于 MCP Python SDK 开发一个标准的 MCP Server,并将其部署至函数计算。在不修改任何业务代码的前提下,通过控制台简单配置,即可实现该服务自动注册至 MSE Nacos 企业版,并支持后续的动态更新与统一管理。
822 78
|
7月前
|
人工智能 运维 安全
配置驱动的动态 Agent 架构网络:实现高效编排、动态更新与智能治理
本文所阐述的配置驱动智能 Agent 架构,其核心价值在于为 Agent 开发领域提供了一套通用的、可落地的标准化范式。
3095 95
|
6月前
|
机器学习/深度学习 人工智能 文字识别
中药材图像识别数据集(100类,9200张)|适用于YOLO系列深度学习分类检测任务
本数据集包含9200张中药材图像,覆盖100种常见品类,已标注并划分为训练集与验证集,支持YOLO等深度学习模型。适用于中药分类、目标检测、AI辅助识别及教学应用,助力中医药智能化发展。
|
6月前
|
弹性计算 搜索推荐 异构计算
阿里云服务器收费标准:包年包月和按量付费费用整理
阿里云服务器提供包年包月与按量付费两种模式,包年包月低至38元起/年,涵盖2核2G到8核32G多款爆款配置,轻量应用服务器享200M峰值带宽不限流量,香港节点25元/月起,GPU服务器亦有优惠,新老用户均可享大幅折扣。
1104 40
|
6月前
|
算法 数据可视化 数据挖掘
空间转录组: Visium CRC 数据集分析
空间转录组: Visium CRC 数据集分析
737 42
空间转录组: Visium CRC 数据集分析
|
6月前
|
JavaScript API 数据安全/隐私保护
5 大主流电商商品详情解析实战手册:淘宝 / 京东 / 拼多多 / 1688 / 唯品会核心字段提取 + 反爬应对 + 代码示例
本文详解淘宝、京东、拼多多、1688、唯品会五大电商平台商品详情页的数据解析逻辑,涵盖价格、SKU、库存、供应商等核心字段提取,针对各平台动态渲染、字体加密、API调用、反爬机制等难点提供完整代码与应对策略,助力开发者高效实现电商数据采集与分析。
|
6月前
|
人工智能 监控 Java
零代码改造 + 全链路追踪!Spring AI 最新可观测性详细解读
Spring AI Alibaba 通过集成 OpenTelemetry 实现可观测性,支持框架原生和无侵入探针两种方式。原生方案依赖 Micrometer 自动埋点,适用于快速接入;无侵入探针基于 LoongSuite 商业版,无需修改代码即可采集标准 OTLP 数据,解决了原生方案扩展性差、调用链易断链等问题。未来将开源无侵入探针方案,整合至 AgentScope Studio,并进一步增强多 Agent 场景下的观测能力。
2651 80
下一篇
开通oss服务