可以。你如果已经掌握了 Spring Boot + MyBatis/MyBatis-Plus + Redis 基础 CRUD,那么 Redis 真正值得学的是它在项目中的"高级用法"。
我建议你不要把 Redis 理解成简单的 key-value 缓存,而是把它看成:
缓存 + 分布式锁 + 分布式计数器 + 延迟队列 + 排行榜 + 限流器 + Session/Token 存储 + 消息系统 + 分布式协调组件
下面我按照 Spring Boot 实际项目开发 的角度,从基础一直讲到高级。
一、Spring Boot 中 Redis 的整体架构
在 Spring Boot 中,最常见的是:
text
Controller
↓
Service
↓
RedisTemplate
↓
Spring Data Redis
↓
Lettuce
↓
Redis Server
现在 Spring Boot 默认通常使用 Lettuce 作为 Redis 客户端。
你会经常接触:
java
RedisTemplate<String, Object>
以及:
java
StringRedisTemplate
二、Redis 在 Spring Boot 中最核心的几个使用场景
实际开发中,可以把 Redis 用法归纳成:
| 场景 | Redis 数据结构 |
|---|---|
| 缓存 | String |
| 对象缓存 | String |
| Hash 对象 | Hash |
| 登录 Token | String |
| 验证码 | String |
| 计数器 | String |
| 点赞 | Set |
| 共同关注 | Set |
| 排行榜 | ZSet |
| 延迟任务 | ZSet |
| 消息队列 | List / Stream |
| 分布式锁 | String |
| 限流 | String / Lua |
| 布隆过滤器 | Bitmap / RedisBloom |
| UV 统计 | HyperLogLog |
| 地理位置 | GEO |
| 实时统计 | Bitmap / HyperLogLog |
所以学习 Redis 高级用法,本质上就是:
掌握 Redis 数据结构 + Spring Data Redis + Lua + 分布式思想。
三、RedisTemplate 高级配置
首先建议项目中不要直接使用默认的:
java
RedisTemplate<Object, Object>
而是自己配置序列化。
例如:
java
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(
RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// Key
StringRedisSerializer stringSerializer =
new StringRedisSerializer();
// Value
GenericJackson2JsonRedisSerializer jsonSerializer =
new GenericJackson2JsonRedisSerializer();
template.setKeySerializer(stringSerializer);
template.setHashKeySerializer(stringSerializer);
template.setValueSerializer(jsonSerializer);
template.setHashValueSerializer(jsonSerializer);
template.afterPropertiesSet();
return template;
}
}
这样 Redis 中看到的数据会比较直观:
text
user:10001
Value:
json
{
"id": 10001,
"username": "zhangsan",
"age": 20
}
而不是:
text
\xac\xed\x00\x05...
四、不要把 Redis 当数据库直接用
这是 Redis 初学者非常容易犯的错误。
比如:
java
redisTemplate.opsForValue()
.set("user:10001", user);
然后所有业务都从 Redis 获取用户。
这通常不是最佳方案。
更合理的是:
text
MySQL
↓
真实数据
Redis
↓
热点数据缓存
也就是:
MySQL 是数据源,Redis 是高速缓存。
五、Redis 最经典的高级用法:缓存
假设:
java
public User getUserById(Long id) {
return userMapper.selectById(id);
}
每次查询:
text
Controller
↓
Service
↓
MySQL
如果访问量很大:
text
10000 QPS
↓
MySQL
数据库压力会非常大。
所以改成:
text
Controller
↓
Service
↓
Redis
↓
Redis有数据 → 返回
Redis没有
↓
MySQL
↓
写入Redis
↓
返回
代码:
java
public User getUserById(Long id) {
String key = "user:" + id;
User user = (User) redisTemplate
.opsForValue()
.get(key);
if (user != null) {
return user;
}
user = userMapper.selectById(id);
if (user != null) {
redisTemplate.opsForValue()
.set(key, user, 30, TimeUnit.MINUTES);
}
return user;
}
这就是最经典的:
Cache Aside Pattern(旁路缓存)
六、缓存更新问题
假设:
text
MySQL:
user.name = 张三
Redis:
text
user:1
{
"name": "张三"
}
现在修改:
java
userMapper.updateById(user);
如果不处理 Redis:
text
MySQL
张三 → 李四
Redis
张三
出现:
缓存和数据库数据不一致
所以更新数据的时候通常:
java
@Transactional
public void updateUser(User user) {
userMapper.updateById(user);
redisTemplate.delete("user:" + user.getId());
}
下次查询:
text
Redis没有
↓
MySQL查询李四
↓
写入Redis
七、为什么推荐"删除缓存"而不是"更新缓存"
很多人会写:
java
userMapper.updateById(user);
redisTemplate.opsForValue()
.set("user:" + user.getId(), user);
看起来没问题。
但并发情况下可能出现:
text
线程A:
更新MySQL
线程B:
查询MySQL旧数据
线程A:
更新Redis新数据
线程B:
把旧数据写入Redis
最终:
text
MySQL:新数据
Redis:旧数据
所以实际项目中经常采用:
text
更新数据库
↓
删除缓存
而不是:
text
更新数据库
↓
更新缓存
八、缓存穿透
这是 Redis 面试非常重要的知识点。
比如:
http
GET /user/999999999
数据库不存在。
流程:
text
Redis → 没有
↓
MySQL → 没有
↓
返回
攻击者不断请求:
text
/user/999999999
/user/999999998
/user/999999997
...
每次 Redis 都没有。
于是:
text
大量请求
↓
Redis
↓
MySQL
↓
MySQL压力巨大
这叫:
缓存穿透
九、解决缓存穿透:缓存空对象
例如:
java
User user = userMapper.selectById(id);
if (user == null) {
redisTemplate.opsForValue()
.set(
"user:" + id,
"",
60,
TimeUnit.SECONDS
);
return null;
}
这样:
text
第一次请求
Redis没有
↓
MySQL没有
↓
Redis写入空值
第二次:
text
Redis
↓
发现空值
↓
直接返回
十、缓存击穿
假设:
text
商品ID:10001
Redis:
product:10001
这是一个超级热门商品。
突然:
text
Redis过期
与此同时:
text
10000个请求
↓
Redis全部miss
↓
10000个请求同时访问MySQL
这就是:
缓存击穿
也叫:
热点 Key 失效问题
十一、解决缓存击穿:互斥锁
核心思想:
text
Redis miss
↓
抢锁
↓
只有一个线程查询MySQL
↓
写Redis
↓
释放锁
其他线程:
text
Redis miss
↓
抢不到锁
↓
等待
↓
再次查询Redis
十二、Redis 分布式锁
最简单的 Redis 锁:
java
Boolean success = redisTemplate.opsForValue()
.setIfAbsent(
"lock:user:10001",
"1",
10,
TimeUnit.SECONDS
);
这里:
java
setIfAbsent()
对应 Redis:
text
SET key value NX EX 10
含义:
text
NX:
key不存在才设置
EX 10:
10秒过期
如果:
java
success == true
说明抢锁成功。
十三、分布式锁为什么一定要设置过期时间
错误:
java
redisTemplate.opsForValue()
.setIfAbsent("lock", "1");
如果 JVM:
text
突然宕机
锁就可能永远存在。
导致:
text
其他线程
↓
永远抢不到锁
所以:
java
setIfAbsent(
key,
value,
10,
TimeUnit.SECONDS
)
是非常重要的。
十四、为什么简单 Redis 锁还不够
假设:
text
线程A
↓
获取锁
value = A
然后:
text
线程A执行很久
锁:
text
10秒过期
于是:
text
线程B
↓
获取锁
value = B
这时候:
text
线程A执行结束
↓
delete(lock)
问题来了。
A 删除的是:
text
B的锁
所以释放锁不能简单:
java
redisTemplate.delete(lockKey);
十五、正确释放锁:Value 唯一标识
例如:
java
String lockValue = UUID.randomUUID().toString();
Boolean success = redisTemplate.opsForValue()
.setIfAbsent(
lockKey,
lockValue,
10,
TimeUnit.SECONDS
);
释放时:
text
检查:
Redis中的value == 当前线程value
如果相同:
删除
但是:
检查 + 删除必须是原子操作。
所以通常使用 Lua。
十六、Lua 释放 Redis 锁
Lua:
lua
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
Spring Boot:
java
DefaultRedisScript<Long> script =
new DefaultRedisScript<>();
script.setScriptText("""
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
""");
script.setResultType(Long.class);
执行:
java
redisTemplate.execute(
script,
Collections.singletonList(lockKey),
lockValue
);
这就是 Redis 高级开发里面非常重要的知识:
Lua + Redis 保证原子性。
十七、实际项目中推荐 Redisson
如果你的项目需要大量使用:
- 分布式锁
- 可重入锁
- 看门狗
- 公平锁
- 读写锁
- 信号量
- CountDownLatch
- 分布式集合
那么不要自己手写全部 Redis 锁。
可以使用:
Redisson
例如:
java
RLock lock = redissonClient.getLock("lock:user:10001");
try {
lock.lock();
// 业务代码
} finally {
lock.unlock();
}
代码非常简单。
Redisson 会帮你处理很多复杂问题。
十八、Redisson 看门狗机制
这是 Redis 分布式锁非常重要的一个高级知识。
假设:
java
lock.lock();
业务执行:
text
30秒
如果锁只有:
text
10秒
就会出现:
text
10秒
↓
锁自动过期
↓
业务还没执行完
Redisson 有:
Watch Dog 看门狗机制
会自动续期:
text
获取锁
↓
30秒
↓
续期
↓
30秒
↓
续期
↓
业务结束
↓
释放锁
所以实际生产项目中:
分布式锁优先考虑 Redisson,而不是自己手搓。
十九、缓存雪崩
假设:
text
100万个缓存
全部设置:
text
30分钟
然后:
text
10:30
↓
大量缓存同时过期
结果:
text
大量请求
↓
Redis miss
↓
MySQL
↓
数据库瞬间压力巨大
这叫:
缓存雪崩
二十、解决缓存雪崩
最常见的方法:
1. TTL 加随机值
不要:
java
30分钟
而是:
java
30分钟 + 随机0~10分钟
例如:
java
long ttl = 30 + ThreadLocalRandom.current()
.nextLong(10);
redisTemplate.opsForValue()
.set(key, value, ttl, TimeUnit.MINUTES);
这样:
text
A:30分钟
B:34分钟
C:37分钟
D:31分钟
E:39分钟
不会同时失效。
二十一、缓存预热
如果你知道:
text
晚上8点
会有大量用户访问:
text
热门课程
热门商品
热门文章
可以提前:
text
MySQL
↓
Redis
例如项目启动:
java
@Component
public class CacheWarmUp {
@PostConstruct
public void init() {
// 查询热门数据
// 写入 Redis
}
}
或者通过:
text
定时任务
消息队列
后台管理系统
进行缓存预热。
二十二、Redis Hash
如果存储用户信息:
text
user:10001
可以使用 Hash:
java
redisTemplate.opsForHash()
.put("user:10001", "name", "张三");
redisTemplate.opsForHash()
.put("user:10001", "age", 20);
Redis:
text
user:10001
name = 张三
age = 20
gender = 男
获取:
java
redisTemplate.opsForHash()
.get("user:10001", "name");
适合:
一个对象里面多个字段,并且可能只修改部分字段。
二十三、Redis Set
Set 最大特点:
元素唯一
例如用户点赞:
text
article:10001:likes
加入:
java
redisTemplate.opsForSet()
.add("article:10001:likes", userId);
判断点赞:
java
redisTemplate.opsForSet()
.isMember("article:10001:likes", userId);
取消:
java
redisTemplate.opsForSet()
.remove("article:10001:likes", userId);
非常适合:
text
点赞
收藏
关注
标签
黑名单
二十四、Set 的高级用法:共同关注
例如:
text
张三关注:
A
B
C
D
李四关注:
B
C
E
F
求共同关注:
java
redisTemplate.opsForSet()
.intersect(
"user:zhangsan:follow",
"user:lisi:follow"
);
结果:
text
B
C
这就是 Redis Set 很强大的地方。
二十五、Redis ZSet:排行榜
ZSet:
text
member
score
例如游戏积分:
text
Tom 1000
Jack 900
Lucy 800
添加:
java
redisTemplate.opsForZSet()
.add("rank:game", "Tom", 1000);
查询排行榜:
java
redisTemplate.opsForZSet()
.reverseRange("rank:game", 0, 9);
就是:
text
Top 10
非常适合:
text
积分排行榜
销量排行榜
热度排行榜
阅读量排行榜
贡献排行榜
二十六、ZSet 还能做延迟队列
这是一个很重要的高级用法。
比如:
text
订单创建
↓
30分钟未支付
↓
自动取消订单
可以:
java
long executeTime =
System.currentTimeMillis()
+ 30 * 60 * 1000;
redisTemplate.opsForZSet()
.add(
"order:delay",
orderId,
executeTime
);
Redis:
text
order:delay
ORDER1001 → 176....
ORDER1002 → 176....
ORDER1003 → 176....
定时扫描:
java
Set<Object> orders =
redisTemplate.opsForZSet()
.rangeByScore(
"order:delay",
0,
System.currentTimeMillis()
);
拿到到期订单:
text
ORDER1001
ORDER1002
然后:
text
取消订单
二十七、但是生产环境不一定推荐自己实现延迟队列
因为:
text
多个服务实例
↓
同时扫描
可能导致:
text
同一个任务
↓
被多个服务执行
所以需要:
text
分布式锁
或者:
text
Redis Stream
RabbitMQ
RocketMQ
Kafka
等专业消息系统。
二十八、Redis List
List 可以实现简单队列:
java
redisTemplate.opsForList()
.rightPush("queue", message);
消费:
java
redisTemplate.opsForList()
.leftPop("queue");
结构:
text
生产者
↓
Redis List
↓
消费者
适合简单任务。
但如果要求:
- 消息确认
- 消费者组
- 消息重试
- 消费进度
- 消息持久化
更推荐:
Redis Stream
二十九、Redis Stream
Redis Stream 是 Redis 5.0 引入的消息结构。
例如:
text
order-stream
生产:
java
redisTemplate.opsForStream()
.add(
StreamRecords.newRecord()
.in("order-stream")
.ofMap(Map.of(
"orderId", "10001"
))
);
消费者组:
text
order-group
消费者:
text
consumer-1
consumer-2
consumer-3
可以实现:
text
消息队列
↓
消费者组
↓
多个消费者
比 List 更适合复杂消息处理。
三十、Redis 计数器
例如文章阅读量:
text
article:10001:views
每访问一次:
java
redisTemplate.opsForValue()
.increment("article:10001:views");
Redis:
text
10001
然后:
text
10002
非常快。
适合:
text
阅读量
点赞量
下载量
访问量
在线人数
三十一、Redis 限流
比如:
text
登录接口
要求:
一个 IP 1分钟最多请求10次。
可以:
text
login:limit:127.0.0.1
使用:
java
Long count = redisTemplate.opsForValue()
.increment(key);
if (count == 1) {
redisTemplate.expire(
key,
1,
TimeUnit.MINUTES
);
}
if (count > 10) {
throw new RuntimeException("请求过于频繁");
}
这就是最简单的:
固定窗口限流
三十二、固定窗口限流的问题
比如:
text
12:00:59
请求10次
12:01:00
又请求10次
短短2秒:
text
20次请求
所以更高级的限流方式有:
text
固定窗口
滑动窗口
令牌桶
漏桶
生产环境可以考虑:
Redisson RateLimiter
例如:
java
RRateLimiter limiter =
redissonClient.getRateLimiter("api:limit");
limiter.trySetRate(
RateType.OVERALL,
100,
1,
RateIntervalUnit.SECONDS
);
意思:
text
整个系统
1秒
最多100次
三十三、Redis Bitmap
Bitmap 非常适合:
签到
例如:
text
用户10001
2026年8月
每天一个 bit:
text
1 0 1 1 0 1 ...
代表:
text
1号:签到
2号:没签到
3号:签到
4号:签到
可以:
java
redisTemplate.opsForValue()
.setBit(
"sign:10001:202608",
0,
true
);
查询:
java
redisTemplate.opsForValue()
.getBit(
"sign:10001:202608",
0
);
非常节省空间。
三十四、Redis HyperLogLog
如果你要统计:
今天有多少独立用户访问网站?
普通 Set:
text
user1
user2
user3
...
如果:
text
1000万用户
Set 占用内存会比较大。
HyperLogLog:
java
redisTemplate.opsForHyperLogLog()
.add(
"uv:20260825",
userId
);
统计:
java
redisTemplate.opsForHyperLogLog()
.size("uv:20260825");
特点:
空间占用极小,但结果是近似值。
所以:
text
UV统计
非常适合。
三十五、Redis GEO
Redis 可以存储地理位置。
例如:
text
商家
经度
纬度
然后查询:
我附近5公里有哪些商家?
Redis GEO 可以完成。
例如:
text
餐厅
酒店
充电桩
附近的人
等场景。
三十六、Spring Cache
如果你使用 Spring Boot,实际上还有一种非常重要的方式:
java
@Cacheable
例如:
java
@Cacheable(
value = "user",
key = "#id"
)
public User getUser(Long id) {
return userMapper.selectById(id);
}
第一次:
text
Redis没有
↓
执行方法
↓
MySQL
↓
自动缓存
第二次:
text
Redis
↓
直接返回
这就是:
Spring Cache 抽象
三十七、@CacheEvict
更新用户:
java
@CacheEvict(
value = "user",
key = "#user.id"
)
public void updateUser(User user) {
userMapper.updateById(user);
}
执行:
text
更新数据库
↓
删除Redis缓存
三十八、@CachePut
如果你希望:
更新数据库以后,同时更新缓存
可以:
java
@CachePut(
value = "user",
key = "#user.id"
)
public User updateUser(User user) {
userMapper.updateById(user);
return user;
}
但是前面说过:
并发场景下缓存更新存在一致性问题。
所以实际项目还是需要根据业务决定。
三十九、缓存一致性高级方案
真正复杂的系统会遇到:
text
MySQL
Redis
MQ
之间的数据一致性问题。
常见方案:
方案一
text
更新MySQL
↓
删除Redis
简单。
方案二
text
更新MySQL
↓
发送MQ消息
↓
删除Redis
适合异步场景。
方案三
text
MySQL Binlog
↓
Canal / Debezium
↓
Redis
这样:
text
MySQL发生变化
↓
监听Binlog
↓
同步Redis
大型系统经常会使用这种思路。
四十、Redis Pipeline
假设你需要执行:
text
1000次Redis操作
普通:
text
请求
↓
Redis
↓
返回
请求
↓
Redis
↓
返回
会产生大量网络 RTT。
Pipeline:
text
客户端
↓↓↓↓↓
Redis
一次发送大量命令。
Spring:
java
redisTemplate.executePipelined(
new SessionCallback<Object>() {
@Override
public Object execute(
RedisOperations operations) {
for (int i = 0; i < 1000; i++) {
operations.opsForValue()
.set("key:" + i, i);
}
return null;
}
}
);
适合:
text
批量读
批量写
缓存预热
数据迁移
四十一、Redis Transaction
Redis 也支持事务:
text
MULTI
↓
命令1
命令2
命令3
↓
EXEC
Spring:
java
redisTemplate.execute(
new SessionCallback<Object>() {
@Override
public Object execute(
RedisOperations operations) {
operations.multi();
operations.opsForValue()
.set("a", "1");
operations.opsForValue()
.set("b", "2");
return operations.exec();
}
}
);
但要注意:
Redis Transaction 和 MySQL Transaction 不是一个概念。
Redis 事务主要解决:
多个 Redis 命令按顺序执行,不被其他客户端插入。
它并不提供 MySQL 那种完整的回滚机制。
四十二、Lua Script
Redis 高级开发非常重要。
比如:
text
判断库存
↓
扣库存
↓
记录订单
如果拆成:
java
getStock();
decreaseStock();
record();
并发情况下可能出现问题。
Lua 可以:
lua
local stock = redis.call('get', KEYS[1])
if tonumber(stock) > 0 then
redis.call('decr', KEYS[1])
return 1
end
return 0
Redis 执行 Lua:
text
整个脚本
↓
Redis内部原子执行
所以:
复杂 Redis 原子操作,Lua 是核心武器。
四十三、库存扣减
例如秒杀:
text
库存100
1000个人同时购买。
不能:
java
Integer stock = getStock();
if (stock > 0) {
decrement();
}
因为:
text
线程A:100
线程B:100
线程C:100
大家都判断:
text
stock > 0
然后一起扣。
所以应该使用:
text
Lua
一次完成:
text
判断库存
+
扣库存
四十四、秒杀系统 Redis 架构
典型架构:
text
Nginx
↓
Spring Boot
↓
Redis预扣库存
↓
MQ
↓
异步创建订单
↓
MySQL
Redis:
text
商品库存
用户是否购买
秒杀资格
限流
MQ:
text
异步削峰
MySQL:
text
最终订单数据
这就是 Redis 在高并发系统中的经典应用。
四十五、Redis 防止重复提交
例如:
text
用户提交考试
前端可能连续点击:
text
提交
提交
提交
可以:
text
submit:exam:userId:examId
第一次:
java
setIfAbsent()
成功:
text
允许提交
第二次:
text
已经存在
↓
拒绝
你的 IELTS 平台这种考试提交、订单提交、任务提交场景都非常适合这个方案。
四十六、Redis Token 管理
登录后:
text
token
↓
Redis
例如:
text
login:token:abc123
Value:
json
{
"userId": 10001,
"username": "zhangsan",
"role": "student"
}
然后:
text
请求
↓
Authorization
↓
Token
↓
Redis
↓
用户信息
这样可以实现:
text
Token过期
强制下线
踢人
单点登录
多端登录控制
四十七、Redis 实现单点登录
例如:
text
用户A
↓
PC
↓
token1
用户A
↓
手机
↓
token2
Redis:
text
user:10001:tokens
token1
token2
如果要求:
同一用户只能登录一个设备。
则:
text
user:10001:token
直接保存当前 Token。
新设备登录:
text
生成token2
↓
覆盖token1
token1 再访问:
text
Redis查询
↓
token不一致
↓
登录失效
四十八、Redis Key 设计非常重要
生产项目中不要随便:
text
user
user1
user2
建议:
text
业务:对象:标识
例如:
text
user:10001
user:10001:profile
article:10001
article:10001:views
article:10001:likes
exam:10001
exam:10001:submit:user:20001
order:10001
order:10001:status
lock:order:10001
这样非常容易维护。
四十九、Redis TTL 一定要合理
不要:
java
set(key, value);
然后永不过期。
否则:
text
Redis
↓
Key越来越多
↓
内存越来越大
一般缓存:
text
5分钟
30分钟
1小时
1天
根据业务设计。
五十、Redis 内存淘汰策略
Redis 内存满了怎么办?
常见策略:
text
noeviction
allkeys-lru
volatile-lru
allkeys-lfu
volatile-lfu
allkeys-random
volatile-random
其中项目里比较值得理解:
LRU
Least Recently Used:
最近最少使用。
LFU
Least Frequently Used:
最不经常使用。
如果你的系统是典型:
text
热门数据
+
大量冷数据
LFU 通常非常值得考虑。
五十一、Redis 持久化
Redis 虽然主要用于缓存,但它也支持持久化。
主要两个:
text
RDB
AOF
RDB
定时生成快照:
text
Redis
↓
dump.rdb
优点:
text
文件小
恢复快
缺点:
text
可能丢失最后一次快照之后的数据
五十二、AOF
AOF:
text
记录写命令
例如:
text
SET user:1 Tom
INCR counter
DEL user:2
Redis 重启:
text
读取AOF
↓
重新执行命令
优点:
text
数据更完整
缺点:
text
文件更大
恢复速度相对慢
生产环境经常:
text
RDB + AOF
一起使用。
五十三、Redis 主从复制
架构:
text
Master
/ \
/ \
Slave1 Slave2
Master:
text
写
Slave:
text
读
可以:
text
读写分离
五十四、Redis Sentinel
如果 Master 挂了:
text
Master
X
谁来接管?
Sentinel:
text
Sentinel
↓
监控Master
↓
发现Master挂掉
↓
选择Slave
↓
提升为Master
实现:
Redis 高可用
五十五、Redis Cluster
如果单台 Redis:
text
内存不够
可以:
text
Redis Cluster
例如:
text
Node1
Node2
Node3
Node4
Node5
Node6
数据根据:
text
Hash Slot
分布到不同节点。
例如:
text
keyA → Node1
keyB → Node3
keyC → Node5
这样可以:
横向扩展 Redis。
五十六、Spring Boot + Redis Cluster
Spring Boot 一般只需要配置:
yaml
spring:
data:
redis:
cluster:
nodes:
- 192.168.1.101:6379
- 192.168.1.102:6379
- 192.168.1.103:6379
Lettuce 会负责:
text
Key
↓
计算 Slot
↓
找到对应节点
一个完整的 Spring Boot Redis 技术体系
你可以把它记成这张图:
text
Redis
│
┌─────────────┼─────────────┐
↓ ↓ ↓
缓存 并发 数据结构
│ │ │
Spring Cache 分布式锁 String
Cache Aside Redisson Hash
穿透 Lua List
击穿 看门狗 Set
雪崩 ZSet
│ │
↓ ↓
一致性 排行榜
Binlog 延迟队列
MQ Bitmap
GEO
HyperLogLog
Stream
│
└──────────────┬──────────────┐
↓ ↓
高并发 高可用
│ │
限流 Sentinel
秒杀 Cluster
库存 主从
削峰