字数:约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 run -d --name redis-stack \ -p 6379:6379 \ -p 8001:8001 \ redis/redis-stack:latest
redis-cli ping
|
核心数据类型: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
| <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
| 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
| FT.SEARCH article_index "Redis"
|
2. 布尔搜索
1 2
| 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.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; 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
| CONFIG SET save "900 1 300 10 60 10000"
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
| FT.CREATE my_index SCHEMA title TEXT WEIGHT 5 content TEXT
|
总结
Redis 8.0带来的Redis Stack,让Redis从单一的缓存服务进化为多模数据库:
- 缓存 → 高性能键值存储
- 搜索 → RedisSearch全文/向量搜索
- 文档 → RedisJSON原生JSON支持
- 图谱 → RedisGraph图数据库
对Java开发者而言,这意味着:
- 一套系统解决多种需求,降低运维复杂度
- 毫秒级响应,满足实时搜索场景
- 与Spring Boot深度集成,学习成本低
Redis Stack不是要替代Elasticsearch,而是在中小规模场景下提供一个更简单、更快速的替代方案。
下一步行动:
- 下载Redis Stack,体验RedisInsight
- 用Docker快速部署一个测试环境
- 迁移一个现有项目的搜索功能到Redis Stack
参考资料:
原创不易,,转发请注明出处。