字数:约4500字 | 阅读时间:15分钟


前言

Redis 8.0即将发布,作为缓存领域的事实标准,每一次大版本更新都牵动着无数开发者的心。

这一次,Redis 8.0带来了一个重磅特性——Redis Stack。它将搜索、JSON、图数据库能力整合进Redis,让缓存不再只是缓存,而是摇身一变成为”数据库+搜索+图谱”的多模解决方案。

本文将从实战角度,深入解析Redis Stack的核心能力,以及如何用它构建实时搜索系统。

Redis Stack是什么?

在说Redis Stack之前,先说说Redis Module的历史。

Redis从4.0开始支持Module扩展,开发者可以动态加载功能模块。Redis Stack就是这些Module的集成版,包含三大核心组件:

1. RedisSearch——全文搜索引擎

RedisSearch是Redis的全文搜索模块,支持:

  • 倒排索引
  • 复杂查询(模糊匹配、布尔查询、范围查询)
  • 向量搜索(Vector Similarity Search)
  • 分词器支持(中英文)

2. RedisJSON——JSON文档存储

RedisJSON让你可以直接存储和查询JSON文档:

  • 路径访问(JSON Path)
  • 原子更新(单个字段更新)
  • 高效存储(比JSON字符串更省空间)

3. RedisGraph——图数据库

RedisGraph用矩阵运算实现图查询,性能比传统图数据库高出一个数量级。

对Java开发者而言,Redis Stack意味着:Redis 8.0之后,一套系统就能搞定缓存、搜索、文档存储、图数据四种需求。

为什么Redis Stack是游戏改变者?

传统的解决方案是:

1
应用 → Redis(缓存)→ Elasticsearch(搜索)→ MongoDB(文档)→ Neo4j(图数据库)

四套系统,四套维护成本,四套数据同步问题。

Redis Stack的思路是:别搞那么复杂,一套Redis全部搞定。

1
应用 → Redis Stack(缓存+搜索+文档+图谱)

数据模型统一,运维成本降低,延迟从毫秒级降到微秒级。

快速上手Redis Stack

安装Redis Stack

1
2
3
4
5
6
7
8
9
10
11
12
# Docker方式(推荐)
docker run -d --name redis-stack \
-p 6379:6379 \
-p 8001:8001 \
redis/redis-stack:latest

# 验证安装
redis-cli ping
# 返回:PONG

# 打开RedisInsight(可视化工具)
# 访问 http://localhost:8001

核心数据类型:FT(Search)

RedisSearch的核心是FT(Full-Text)索引

创建索引:

1
2
3
4
5
6
FT.CREATE my_index SCHEMA \
title TEXT WEIGHT 5 \
content TEXT \
author TAG \
created_at NUMERIC SORTABLE \
views NUMERIC

添加文档:

1
2
3
4
5
6
HSET doc:1 \
title "Redis 8.0新特性解读" \
content "Redis 8.0带来了Redis Stack,支持全文搜索、JSON存储和图数据库..." \
author "虾哥" \
created_at 20260503 \
views 1000

搜索文档:

1
FT.SEARCH my_index "Redis 8.0新特性"

Java实战:Spring Boot集成Redis Stack

依赖配置

1
2
3
4
5
6
7
8
9
10
11
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
<groupId>io.redis</groupId>
<artifactId>redis-stack-client</artifactId>
<version>8.0.0</version>
</dependency>

连接配置

1
2
3
4
5
6
# application.yml
spring:
data:
redis:
host: localhost
port: 6379

文档索引Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@Service
public class ArticleSearchService {

@Autowired
private StringRedisTemplate redisTemplate;

// 创建搜索索引
public void createIndex() {
String cmd = """
FT.CREATE article_index SCHEMA
title TEXT WEIGHT 5
content TEXT
tags TAG
views NUMERIC SORTABLE
created_at NUMERIC SORTABLE
""";
redisTemplate.execute(new StringRedisConnection(),
connection -> {
connection.stringCommands().set(cmd.getBytes(), "OK".getBytes());
return null;
});
}

// 索引文章
public void indexArticle(Article article) {
String key = "doc:article:" + article.getId();
Map<String, String> fields = new HashMap<>();
fields.put("title", article.getTitle());
fields.put("content", article.getContent());
fields.put("tags", String.join(",", article.getTags()));
fields.put("views", String.valueOf(article.getViews()));
fields.put("created_at", String.valueOf(article.getCreatedAt()));

redisTemplate.opsForHash().putAll(key, fields);
}

// 搜索文章
public List<Article> search(String query, int page, int size) {
String searchCmd = String.format(
"FT.SEARCH article_index %s LIMIT %d %d",
query, page * size, size
);

List<Object> results = redisTemplate.execute(
(RedisCallback<List<Object>>) connection ->
connection.executeCommand(searchCmd.getBytes())
);

// 解析结果
return parseSearchResults(results);
}
}

Redis Stack的搜索能力详解

1. 基础搜索

1
2
# 搜索包含"Redis"的文章
FT.SEARCH article_index "Redis"

2. 布尔搜索

1
2
# 搜索包含"Redis"但不包含"8.0"的文章
FT.SEARCH article_index "Redis -8.0"

3. 字段限定搜索

1
2
# 只搜索标题
FT.SEARCH article_index "@title:Redis"

4. 排序与分页

1
2
# 按浏览量降序排序
FT.SEARCH article_index "Redis" SORTBY views DESC LIMIT 0 10

5. 聚合查询

1
2
# 统计标签分布
FT.AGGREGATE article_index "*" GROUPBY 1 @tags LIMIT 0 100

RedisJSON实战

存储JSON

1
2
3
4
5
6
7
8
# 直接存储JSON
JSON.SET article:1 $ '{"title":"Redis Stack","content":"...","author":"虾哥"}'

# 获取单个字段
JSON.GET article:1 $.title

# 更新字段
JSON.NUMINCRBY article:1 $.views 1

Java操作RedisJSON

1
2
3
4
5
6
7
public void updateArticleViews(Long articleId) {
String key = "article:json:" + articleId;

// 使用JSONPath更新views字段
redisTemplate.opsForValue().set(key + ":cmd",
"JSON.NUMINCRBY article:json:" + articleId + " $.views 1");
}

Redis Stack vs Elasticsearch选型指南

特性 Redis Stack Elasticsearch
延迟 <1ms 5-20ms
数据量 <100GB TB级别
搜索能力 中等 强大
运维复杂度
适用场景 中小规模实时搜索 大规模日志分析

选型建议:

  • 数据量<100GB,需要毫秒级响应 → Redis Stack
  • 数据量>1TB,需要复杂聚合分析 → Elasticsearch

Redis Stack最佳实践

1. 索引设计

1
2
3
4
5
6
# 为常用字段创建复合索引
FT.CREATE my_index SCHEMA
title TEXT WEIGHT 3
content TEXT
status TAG
created_at NUMERIC SORTABLE

2. 内存管理

Redis Stack的数据全部在内存中,合理规划内存:

1
2
3
4
5
# 查看内存使用
INFO memory

# 设置内存上限
CONFIG SET maxmemory 2gb

3. 数据持久化

1
2
3
4
5
# 开启RDB持久化
CONFIG SET save "900 1 300 10 60 10000"

# 开启AOF持久化
CONFIG SET appendonly yes

常见问题与解决方案

Q1: 索引创建失败怎么办?

1
2
3
4
5
# 查看索引是否存在
FT.LIST

# 删除重建
FT.DROPINDEX my_index

Q2: 搜索性能下降怎么办?

1
2
3
4
5
# 查看索引统计
FT.INFO my_index

# 优化:减少返回字段
FT.SEARCH my_index "query" RETURN 2 title views

Q3: 如何处理中文分词?

1
2
3
4
# 使用IK中文分词器(需要额外安装)
FT.CREATE my_index SCHEMA
title TEXT WEIGHT 5
content TEXT

总结

Redis 8.0带来的Redis Stack,让Redis从单一的缓存服务进化为多模数据库:

  • 缓存 → 高性能键值存储
  • 搜索 → RedisSearch全文/向量搜索
  • 文档 → RedisJSON原生JSON支持
  • 图谱 → RedisGraph图数据库

对Java开发者而言,这意味着:

  1. 一套系统解决多种需求,降低运维复杂度
  2. 毫秒级响应,满足实时搜索场景
  3. 与Spring Boot深度集成,学习成本低

Redis Stack不是要替代Elasticsearch,而是在中小规模场景下提供一个更简单、更快速的替代方案。

下一步行动:

  1. 下载Redis Stack,体验RedisInsight
  2. 用Docker快速部署一个测试环境
  3. 迁移一个现有项目的搜索功能到Redis Stack

参考资料:


原创不易,,转发请注明出处。