Redis Starter
受众:开发者 摘要:Spring Data Redis + Redisson 集成。
RedisManager/RedissonManager/ Topic / 分布式锁 / JSON 序列化 / 多实例 Pub/Sub 底座。
何时使用
| 场景 | 建议 |
|---|---|
| 普通业务缓存 | 用 cache.md Facade,不直接用 RedisManager |
| Redis 数据结构(Hash / List / ZSet / Set) | RedisManager |
| 简单分布式锁(随机 token + Lua 释放) | redisManager.tryLock(...) |
| 看门狗续期锁、Topic、RAtomicLong 等 | RedissonManager |
| 配置多实例广播 | spring.open.config.refresh.provider=redis |
| WebSocket 多实例 | spring.open.websocket.cluster.enabled=true |
| Sa-Token 跨实例登录态共享 | spring.open.auth.persistence.store=redis |
| 单进程隔离诊断(无 Redis) | 关掉 starter 或全切 memory provider;普通开发不推荐绕开 Redis |
Redis 是缓存和协调工具,不是长期事实数据源。重要业务数据必须落数据库。
机制说明
Data Redis starter 复用 Spring Boot 标准 spring.data.redis.* 连接信息,并在框架侧提供两层统一入口:
| 入口 | 适用范围 | 机制边界 |
|---|---|---|
RedisManager | String / Hash / List / Set / ZSet、TTL、计数、轻量锁 | 统一 key 前缀和 JSON 序列化;轻量锁使用随机 token + Lua 校验释放;不负责业务缓存策略和长期数据一致性 |
RedissonManager | 看门狗锁、Topic、限流器、Redisson 高级对象 | 所有业务 key 仍经过 RedisKeyResolver;需要高级协调能力时使用,普通业务缓存不要直接依赖 |
RedissonClient | Facade 暂未覆盖的 Redisson 原生能力 | 仅限高级场景,业务模块应优先尝试 RedisManager / RedissonManager |
key 解析由 RedisKeyResolver 集中处理。业务代码只传 auth:token:1、job:daily 这类业务 key,starter 会补齐应用级命名空间;如果 key 已经带当前前缀,则保持幂等返回。
Redisson 配置由 RedissonConfigFactory 生成,不使用 Redisson Spring Boot starter。mode=auto 时按 cluster -> sentinel -> single 顺序推断连接模式;用户名、密码、库编号和 SSL 默认沿用 Spring Boot Redis 配置,避免维护两套连接凭据。
快速开始
spring:
data:
redis:
host: 127.0.0.1
port: 6379
password:
database: 0
open:
data:
redis:
enabled: true注入:
@RequiredArgsConstructor
@Service
public class SampleCacheService {
private final RedisManager redisManager;
private final RedissonManager redissonManager;
}环境变量:
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DATABASE=0Cluster / Sentinel 用 Spring Boot 标准 spring.data.redis.cluster.* / spring.data.redis.sentinel.*。Redisson 默认复用同一连接信息。
Facade API
RedisManager(基础操作)
String:
redisManager.set("sample:value", Map.of("name", "Alice"), Duration.ofMinutes(10));
Object value = redisManager.get("sample:value");
SampleValueVO vo = redisManager.get("sample:value", SampleValueVO.class);Hash / List / Set / ZSet:
redisManager.hSet("sample:hash", "name", "Alice");
String name = redisManager.hGet("sample:hash", "name", String.class);
redisManager.lRightPush("sample:list", "a");
Object popped = redisManager.lLeftPop("sample:list");
redisManager.sAdd("sample:set", "a", "b");
boolean exists = redisManager.sIsMember("sample:set", "a");
redisManager.zAdd("sample:zset", "task-1", System.currentTimeMillis());
Set<Object> tasks = redisManager.zRange("sample:zset", 0, 10);TTL / 计数:
redisManager.expire("sample:value", Duration.ofMinutes(5));
Duration ttl = redisManager.ttl("sample:value");
Long count = redisManager.increment("sample:counter");
redisManager.decrement("sample:counter", 2);轻量锁(随机 token + Lua 释放,避免误删别人的锁):
Optional<RedisLock> lock = redisManager.tryLock("lock:order:1", Duration.ofSeconds(30));
if (lock.isEmpty()) return;
try {
// 业务逻辑
} finally {
redisManager.unlock(lock.get());
}RedissonManager(高级协调)
看门狗续期锁:
boolean executed = redissonManager.tryWithLock(
"lock:job:daily-report",
Duration.ofSeconds(1),
Duration.ofMinutes(5),
() -> {
// 只允许一个实例执行
});
Optional<String> value = redissonManager.tryWithLock(
"lock:build:summary",
Duration.ofSeconds(1),
Duration.ofSeconds(30),
() -> "ok");Topic:
RTopic topic = redissonManager.topic("config:changed");
topic.publish("refresh");原生客户端(仅当抽象未覆盖时使用):
RedissonClient client = redissonManager.client();配置项
spring:
open:
data:
redis:
enabled: true
key-prefix: "" # 空时回退 spring:open:${spring.application.name}
default-lock-ttl: 30s
redisson:
enabled: true
mode: auto # auto / single / cluster / sentinel
address: ""
timeout: 3s
connect-timeout: 10s
retry-attempts: 3
retry-interval: 1500ms
lock-watchdog-timeout: 30s
lazy-initialization: true
threads: 0
netty-threads: 0| 配置 | 默认值 | 说明 |
|---|---|---|
enabled | true | 启用 Data Redis starter |
key-prefix | 空 | 应用级 key 前缀 |
default-lock-ttl | 30s | RedisManager 基础锁默认 TTL |
redisson.enabled | true | 启用 Redisson |
redisson.mode | auto | 连接模式 |
redisson.lock-watchdog-timeout | 30s | 看门狗超时 |
mode=auto 推断规则:
| 模式 | 触发条件 |
|---|---|
single | 默认 |
cluster | 配了 spring.data.redis.cluster.nodes |
sentinel | 配了 spring.data.redis.sentinel.master |
项目不用 Redisson Spring Boot starter,直接接入 Redisson core,避开 Spring Boot 4 自动配置生命周期强绑定。
Key 前缀
默认:
spring:open:${spring.application.name}业务 key cache:user:1 → 实际 Redis key spring:open:spring-open-application:cache:user:1
覆盖:
spring:
open:
data:
redis:
key-prefix: sample业务代码不自己拼应用级前缀,交给 RedisKeyResolver 或 RedisManager。
序列化
appRedisTemplate:
| 部分 | 序列化器 |
|---|---|
| key / hash key | StringRedisSerializer.UTF_8 |
| value / hash value | GenericJacksonJsonRedisSerializer |
当前用 Spring Data Redis 4 + Jackson 3。对象结构变化时跨版本长期数据不依赖 Redis value 作唯一来源。
Sa-Token 持久化复用 Spring Data Redis,但使用 auth 模块自己的 key 前缀。
Provider
Data Redis 本身不提供 Provider 切换。扩展能力:
- 自定义
RedisSerializerBean 覆盖默认 JSON 序列化 - 自定义
RedisKeyResolverBean 改 key 前缀策略 - 通过
RedissonConfigCustomizer调整 Redisson 高级参数
上层模块复用
| 能力 | Redis 用途 |
|---|---|
| Cache | redis store,默认共享缓存 |
| Auth | spring.open.auth.persistence.store=redis 跨实例登录态 |
| Config | 远程缓存 + Pub/Sub 多实例刷新 |
| Queue | redis provider 基于 List |
| Scheduler | redis provider 基于 ZSet + Hash + 执行锁 |
| WebSocket | 多实例广播基于 Redisson Topic |
上层模块只依赖各自 Facade,不直接操作底层 Redis key。
Config 多实例刷新
spring:
open:
config:
refresh:
provider: redis
redis-channel: config:changedPub/Sub 不是可靠队列:实例短暂离线可能错过广播。关键配置以数据库 + 缓存 TTL 兜底。
WebSocket 多实例
spring:
open:
websocket:
cluster:
enabled: true
topic: websocket:commandsTopic 自动叠加 key 前缀,跨实例发送、广播和关闭连接走 Topic。
隔离诊断(无 Redis)
spring:
open:
cache:
default-provider: memory
auth:
persistence:
store: memory
queue:
provider: memory
scheduler:
provider: memory或关 starter:
spring:
open:
data:
redis:
enabled: false完整模式仍建议保留 Redis:缓存、登录态、多实例刷新和轻量协调能力开箱可用。
开发约定
- 普通业务缓存用
CacheFacade,不散落RedisTemplate - Redis 数据结构 / 锁 / Topic / 底层协调用
RedisManager/RedissonManager - key 命名冒号分层:
cache:user:1/lock:order:1/queue:default - key 不含明文手机号、邮箱、token、私钥
- 锁必须设 TTL,并在
finally中释放 - Pub/Sub 只做通知,不承载必须送达的数据
- 多实例状态以数据库保证最终一致,Redis 负责加速和协调
验证命令
./mvnw -pl spring-open-starters/spring-open-starter-data-redis -am test -DskipITs
./mvnw -pl spring-open-application -am test -DskipITs -DskipFrontend相关
- 业务缓存底座:cache.md
- 队列 / 任务调度:queue.md / scheduler.md
- 配置多实例刷新:config.md
- WebSocket 多实例:websocket.md
- Provider 扩展模型:provider.md