这是一篇为您准备的关于 Redis JSON 的快速上手指南,涵盖了核心概念、命令详解以及实战场景。
Redis JSON 快速上手:命令详解与实战案例
在 Redis 的演进历史中,Redis JSON (RedisJSON) 模块的出现是一个重要的里程碑。它打破了过去只能将 JSON 数据当作“字符串”存储的限制,允许我们在 Redis 中以原生 JSON 格式存储、读取和更新数据。
本文将带您快速掌握 Redis JSON 的核心用法,并通过实战案例展示其强大之处。
1. 为什么需要 Redis JSON?
在没有 RedisJSON 之前,如果我们想在 Redis 中存储一个用户对象:
* 方案 A (String):将对象序列化为 JSON 字符串存入。
* 缺点:每次只想修改一个字段(如修改年龄),必须把整个字符串取出来,反序列化,修改,再序列化,再存回去。并发高时容易覆盖数据。
* 方案 B (Hash):将对象的每个字段存为 Hash 的 field。
* 缺点:无法很好地处理嵌套结构(如对象里还有数组)。
RedisJSON 的优势:
* 原生支持:直接存储 JSON 结构。
* 原子操作:可以直接修改 JSON 内部的某个字段(如 user.age),无需全量读取和写入。
* 高性能:基于内存的树状结构存储,读写子元素速度极快。
* 类型安全:严格遵循 JSON 标准。
2. 环境准备
最简单的使用方式是安装 Redis Stack,它默认集成了 RedisJSON、RediSearch 等常用模块。
如果您使用 Docker,可以一键启动:
bash
docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
3. 核心命令详解
RedisJSON 的命令都以 JSON. 开头。所有的操作都需要指定一个 key 和一个 JSON Path(路径)。
* $ 代表根节点。
* .field 代表子字段。
3.1 写入数据 (JSON.SET)
保存一个 JSON 对象。
“`bash
语法: JSON.SET
保存一个用户对象
127.0.0.1:6379> JSON.SET user:1001 $ ‘{“name”: “Alice”, “age”: 25, “tags”: [“design”, “coding”]}’
OK
“`
3.2 读取数据 (JSON.GET)
读取整个对象或特定字段。
“`bash
读取完整数据
127.0.0.1:6379> JSON.GET user:1001
“{\”name\”:\”Alice\”,\”age\”:25,\”tags\”:[\”design\”,\”coding\”]}”
只读取 name 字段 (高效)
127.0.0.1:6379> JSON.GET user:1001 $.name
“[\”Alice\”]”
读取多个字段
127.0.0.1:6379> JSON.GET user:1001 $.name $.age
“{\”$.name\”:[\”Alice\”],\”$.age\”:[25]}”
“`
注意:返回结果通常包在数组中,因为 JSON Path 可能匹配多个元素。
3.3 数值操作 (JSON.NUMINCRBY)
直接在 Redis 内部对 JSON 中的数值进行增减,无需取出计算。
“`bash
让 Alice 的年龄 +1
127.0.0.1:6379> JSON.NUMINCRBY user:1001 $.age 1
“[26]”
“`
3.4 数组操作 (JSON.ARRAPPEND, JSON.ARRLEN)
直接向数组追加元素,非常适合标签、购物车等场景。
“`bash
向 tags 数组追加一个 “travel”
127.0.0.1:6379> JSON.ARRAPPEND user:1001 $.tags ‘”travel”‘
(integer) 3
获取数组长度
127.0.0.1:6379> JSON.ARRLEN user:1001 $.tags
(integer) 3
“`
3.5 切换布尔值 (JSON.TOGGLE)
需 RedisJSON 2.0+
“`bash
假设有一个 isActive 字段
127.0.0.1:6379> JSON.SET user:1001 $.isActive true
OK
127.0.0.1:6379> JSON.TOGGLE user:1001 $.isActive
“[false]”
“`
3.6 删除数据 (JSON.DEL)
“`bash
删除 tags 字段
127.0.0.1:6379> JSON.DEL user:1001 $.tags
(integer) 1
“`
4. 实战案例:电商购物车
假设我们要实现一个简单的购物车功能。每个用户的购物车是一个 JSON 对象,包含商品列表。
数据结构设计:
json
{
"cart_id": "cart:u123",
"items": [
{ "id": "p1", "price": 100, "qty": 1 },
{ "id": "p2", "price": 50, "qty": 2 }
],
"updated_at": 1700000000
}
场景 1:初始化购物车
用户第一次添加商品时,初始化购物车结构。
bash
JSON.SET cart:u123 $ '{"items": [], "updated_at": 0}'
场景 2:添加商品
用户添加了一件商品。我们直接向 items 数组追加数据。
bash
JSON.ARRAPPEND cart:u123 $.items '{"id": "p3", "price": 200, "qty": 1}'
场景 3:修改购买数量
用户将商品列表里第一个商品的数量增加 1。
注意:这里我们假设已知商品在数组中的索引是 0。实际业务中可能配合搜索或应用层逻辑使用。
bash
JSON.NUMINCRBY cart:u123 $.items[0].qty 1
场景 4:查询购物车总览
只获取商品列表,不需要元数据。
bash
JSON.GET cart:u123 $.items
5. 总结
Redis JSON 的核心价值在于“细粒度操作”。
| 对比维度 | 普通 Redis String (JSON 序列化) | Redis JSON |
|---|---|---|
| 读取性能 | 读取整个 JSON 字符串 | 可只读取特定字段,网络开销小 |
| 写入性能 | 必须全量覆盖 | 可只修改特定字段,极快 |
| 并发安全 | 需配合 Watch/Lua 脚本 | 单个命令原子执行,天然安全 |
| 复杂度 | 客户端需频繁序列化/反序列化 | 数据库侧原生处理 |
如果您的业务中大量涉及复杂的嵌套对象,且需要频繁修改其中的属性(如用户配置、游戏存档、实时大屏数据),Redis JSON 是一个无可替代的神器。