一、RedisJSON:原生 JSON 支持的 NoSQL 数据引擎
1. 简介
RedisJSON 为 Redis 增加了对 JSON 文档的原生存储与操作能力,无需序列化/反序列化即可直接读写嵌套字段,适用于配置管理、用户画像、微服务间数据交换等场景。
2. 核心原理
RedisJSON 使用ReJSON 引擎,底层基于树状结构(Tree-based)存储 JSON 对象,支持按路径(JSONPath)高效访问子节点。内存布局优化避免深拷贝,提升读写性能。
3. 常用命令
| 命令 | 示例 | 说明 |
|---|---|---|
JSON.SET | JSON.SET user:1 $.profile.age 28 | 设置 JSON 字段 |
JSON.GET | JSON.GET user:1 $.profile.name | 获取指定路径值 |
JSON.DEL | JSON.DEL user:1 $.temp | 删除字段 |
JSON.NUMINCRBY | JSON.NUMINCRBY sensor:1 $.value 1.5 | 数值原子递增 |
JSON.TYPE | JSON.TYPE user:1 $ | 返回 JSON 类型 |
4. 应用场景
- 用户资料动态更新(避免全量覆盖)
- IoT 设备状态快照存储
- 微服务间传递结构化配置
二、RedisSearch:高性能全文搜索与二级索引
1. 简介
RedisSearch 提供倒排索引、向量相似度搜索、聚合分析等功能,可替代 Elasticsearch 在轻量级场景中的角色。
2. 核心原理
- 基于倒排索引(Inverted Index)实现文本搜索
- 支持数值范围索引、地理空间索引、向量索引(HNSW/FLAT)
- 使用FST(有限状态转换器)压缩索引,节省内存
3. 常用命令
FT.CREATE:定义索引结构FT.SEARCH:执行全文/条件搜索FT.AGGREGATE:分组聚合(如按城市统计用户数)FT.INFO:查看索引状态FT.DROPINDEX:删除索引
4. 应用场景
- 商品搜索(支持多字段过滤+排序)
- 日志关键词检索
- 向量相似推荐(如“猜你喜欢”)
三、RedisBloom:概率数据结构利器(布隆过滤器为核心)
1. 简介
RedisBloom 提供布隆过滤器(Bloom Filter)、Cuckoo Filter、Top-K、Count-Min Sketch 等概率数据结构,用于高效去重、存在性判断、流量统计。
2. 布隆过滤器原理
- 使用k 个哈希函数将元素映射到位数组
- 查询时若任一位为 0,则元素一定不存在;若全为 1,则可能存在(有误判率)
- 空间效率极高,1MB 可支持千万级元素
3. 常用命令
BF.RESERVE key error_rate capacity:预分配过滤器BF.ADD / BF.MADD:添加单个元素/多个元素BF.EXISTS / BF.MEXISTS:查询单个元素存在性/多个元素存在性CF.ADD / CF.EXISTS:Cuckoo Filter(支持删除)
5. 应用场景
- 防止缓存穿透(先查 Bloom 判断 key 是否合法)
- 爬虫 URL 去重
- 实时 UV 统计(配合 HyperLogLog)
四、RedisTimeSeries:高性能时序数据处理
1. 简介
专为时间序列数据(如监控指标、传感器数据)设计,支持自动压缩、降采样、聚合查询。
2. 核心原理
- 数据按时间戳有序存储,使用块压缩(Chunk Compression)减少内存
- 支持保留策略(RETENTION)自动过期旧数据
- 可与 Redis Streams 或 Grafana 集成
3. 常用命令
TS.CREATE metrics:cpu RETENTION 86400000 LABELS host server1TS.ADD metrics:cpu * 45.6(* 表示当前时间戳)TS.RANGE metrics:cpu 1700000000 1700010000 AGGREGATION avg 60TS.MRANGE ... FILTER host=server1(多序列查询)
4. 应用场景
- 服务器监控(CPU/内存/网络)
- IoT 设备数据采集
- 金融行情 tick 数据存储
五、RedisGraph:图数据库初探
1. 简介
基于属性图模型,使用Cypher 查询语言,适合社交关系、知识图谱、欺诈检测等场景。
2. 核心原理
- 图数据以稀疏矩阵(CSR 格式)存储
- 查询引擎支持模式匹配与路径遍历
- 所有操作在单次 Redis 调用中完成,低延迟
3. 常用命令
GRAPH.QUERY:执行 Cypher 语句GRAPH.DELETE:删除图GRAPH.EXPLAIN:查看执行计划
4. 应用场景
- 社交网络好友推荐
- 反欺诈(识别异常转账环路)
- 知识图谱实体关系查询
六、模块对比总表
| 模块 | 核心功能 | 数据模型 | 是否支持集群 | 典型延迟 | 适用场景 |
|---|---|---|---|---|---|
| RedisJSON | JSON 原生操作 | 文档 | ✅(Redis Stack 8.0+) | <1ms | 动态配置、用户画像 |
| RedisSearch | 全文/向量搜索 | 索引 | ✅ | 1–10ms | 商品搜索、日志分析 |
| RedisBloom | 概率去重 | 位图/哈希 | ✅ | <0.1ms | 缓存穿透防护、爬虫去重 |
| RedisTimeSeries | 时序数据 | 时间序列 | ✅ | <1ms | 监控、IoT |
| RedisGraph | 图关系查询 | 属性图 | ❌ | 1–50ms | 社交网络、反欺诈 |
七、实战演练
1. 安装redis-stack
Redis 官方提供的集成了多个模块的镜像
dockerrun-p6379:6379-it--rmredis/redis-stack:latest2. RedisJSON 实战:用户画像动态管理
场景:存储和更新用户资料(支持嵌套字段)
# 1. 创建用户 JSON 文档JSON.SET user:1001 $'{"name":"Alice","profile":{"age":28,"city":"Shanghai","tags":["developer","gamer"]},"settings":{"theme":"dark","lang":"zh"}}'# 2. 获取用户姓名JSON.GET user:1001 $.name# 返回: "\"Alice\""# 3. 更新年龄(原子递增)JSON.NUMINCRBY user:1001 $.profile.age1# 返回: "29"# 4. 添加新标签JSON.ARRAPPEND user:1001 $.profile.tags'"mobile"'# 返回: 3(数组长度)# 5. 查询所有 tagsJSON.GET user:1001 $.profile.tags# 返回: "[\"developer\",\"gamer\",\"mobile\"]"# 6. 删除 settings 字段JSON.DEL user:1001 $.settings# 返回: 1(成功删除 1 个字段)验证完整文档:
JSON.GET user:1001 $3. RedisSearch 实战:商品搜索系统
场景:电商商品全文检索 + 多条件过滤
# 1. 创建商品索引(支持文本、数值、标签)FT.CREATE idx:products ON HASH PREFIX1product: SCHEMA name TEXT WEIGHT2.0description TEXT price NUMERIC category TAG in_stock NUMERIC# 2. 添加商品数据HSET product:101 name"Wireless Headphones"description"Noise-cancelling Bluetooth headphones"price129.99category"electronics"in_stock1HSET product:102 name"Running Shoes"description"Lightweight trail running shoes"price89.99category"sports"in_stock1HSET product:103 name"Smart Watch"description"Fitness tracker with heart rate monitor"price199.99category"electronics"in_stock0# 3. 全文搜索“headphones”,且有库存FT.SEARCH idx:products"@name:headphones @in_stock:[1 1]"# 4. 按价格区间 + 类别搜索FT.SEARCH idx:products"@category:{electronics} @price:[100 200]"RETURN2name price# 5. 聚合:统计各分类商品数FT.AGGREGATE idx:products"*"GROUPBY1@category REDUCE COUNT0AS count预期结果示例(第4步):
1)(integer)22)"product:101"3)1)"name"2)"Wireless Headphones"3)"price"4)"129.99"4)"product:103"5)1)"name"2)"Smart Watch"3)"price"4)"199.99"参数解释
| 语法片段 | 含义 |
|---|---|
ON HASH | 索引的数据源是 Redis 的 Hash 类型键 |
PREFIX 1 product: | 仅对 key 名以product:开头的 Hash 自动建索引 |
1 | 表示后面有 1 个前缀(支持多个,如PREFIX 2 a: b:) |
如果省略 PREFIX,RedisSearch 不会自动索引任何已有或新增的 Hash
4. RedisBloom 实战:防止缓存穿透(URL 黑名单)
场景:爬虫请求过滤,避免查询不存在的资源
# 1. 创建布隆过滤器(误判率 1%,容量 10,000)BF.RESERVE url_blacklist0.0110000# 2. 添加恶意 URLBF.ADD url_blacklist"/admin/delete"BF.ADD url_blacklist"/api/v1/secret"# 3. 模拟正常请求(应返回 0)BF.EXISTS url_blacklist"/user/profile"# 返回: 0 → 安全,可继续处理# 4. 模拟恶意请求(应返回 1)BF.EXISTS url_blacklist"/admin/delete"# 返回: 1 → 拦截!# 5. 批量检查(用于日志分析)BF.MEXISTS url_blacklist"/login""/admin/delete""/health"# 返回: 0 1 0注意:即使返回 1,也可能是误判(但概率 ≤1%),需结合其他策略。
5. RedisTimeSeries 实战:服务器 CPU 监控
场景:每秒采集 CPU 使用率,自动保留 7 天
# 1. 创建时序 key,保留 7 天(604800 秒),标签用于聚合TS.CREATE metrics:cpu:server01 RETENTION604800LABELShostserver01typecpu# 2. 模拟写入 5 个时间点的数据(时间戳单位:毫秒)TS.ADD metrics:cpu:server01171000000000023.5TS.ADD metrics:cpu:server01171000006000045.2TS.ADD metrics:cpu:server01171000012000067.8TS.ADD metrics:cpu:server01171000018000032.1TS.ADD metrics:cpu:server01171000024000089.0# 3. 查询最近 5 分钟数据(按 1 分钟平均聚合)TS.RANGE metrics:cpu:server0117100000000001710000300000AGGREGATION avg60000# 4. 多服务器聚合(需先创建多个 series)TS.CREATE metrics:cpu:server02 RETENTION604800LABELShostserver02typecpu TS.ADD metrics:cpu:server02171000000000018.3# 5. 查询所有 CPU 指标(按 host 分组)TS.MRANGE17100000000001710000300000FILTERtype=cpu聚合输出示例(第3步):
1) 1) (integer) 1710000000000 2) "34.35" 2) 1) (integer) 1710000060000 2) "56.5" ...参数解释
| 语法 | 作用 |
|---|---|
LABELS key1 val1 key2 val2 ... | 为时间序列添加多个键值对标签 |
| 用途 | 支持TS.MRANGE多维过滤、聚合、可视化分组 |
| 最佳实践 | 用host,region,service,metric_type等作为通用标签 |
6. RedisGraph 实战:社交网络好友关系
场景:查找“朋友的朋友”
# 1. 构建图:添加用户和好友关系GRAPH.QUERY social" MERGE (a:Person {id:'1', name:'Alice'}) MERGE (b:Person {id:'2', name:'Bob'}) MERGE (c:Person {id:'3', name:'Charlie'}) MERGE (d:Person {id:'4', name:'David'}) MERGE (a)-[:FRIEND]->(b) MERGE (b)-[:FRIEND]->(c) MERGE (a)-[:FRIEND]->(d) "# 2. 查询 Alice 的直接好友GRAPH.QUERY social" MATCH (a:Person {name:'Alice'})-[:FRIEND]->(f) RETURN f.name "# 3. 查询“朋友的朋友”(排除自己和直接好友)GRAPH.QUERY social" MATCH (a:Person {name:'Alice'})-[:FRIEND]->()-[:FRIEND]->(foaf) WHERE foaf.name <> 'Alice' RETURN DISTINCT foaf.name "# 4. 查看图结构统计GRAPH.QUERY social"CALL db.labels()"GRAPH.QUERY social"CALL db.relationshipTypes()"第3步预期结果:
1) 1) "foaf.name" 2) 1) "Charlie"说明:Alice → Bob → Charlie,所以 Charlie 是“朋友的朋友”。
八、高频面试题
Q1:RedisBloom 的布隆过滤器为什么不能删除元素?如何解决?
A:标准布隆过滤器使用位数组,多个元素可能共享同一位,删除会导致误删。解决方案是使用Cuckoo Filter(RedisBloom 支持),它支持安全删除。
Q2:RedisJSON 和普通 String 存 JSON 有什么区别?
A:String 需全量读写和反序列化,而 RedisJSON 支持路径级原子操作,内存更省、性能更高,且支持 JSONPath 查询。
客户端反序列化 → 修改 login_count → 重新序列化
(这一步在你的应用代码里完成,比如 Python/Java)
String存 JSON = 把整个书复印一遍再改一个字
RedisJSON = 直接在原书上用笔修改那个字,又快又省纸。
Q3:RedisSearch 能替代 Elasticsearch 吗?
A:在中小规模、低复杂度场景(如商品搜索、日志关键词)可以;但 ES 在分布式扩展、复杂分析、生态工具上仍占优。RedisSearch 优势在于低延迟、高吞吐、与 Redis 生态无缝集成。
Q4:RedisTimeSeries 如何实现数据压缩?
A:采用Delta-of-Delta + Simple-8b 编码,对时间戳和值进行差分压缩,通常可减少 70%+ 内存占用。
Q5:RedisGraph 不支持集群,如何应对大数据量?
A:可采用分片策略(如按用户 ID 分图),或仅用于高频小图查询,大图分析交由专用图数据库(如 Neo4j)。