Redis 6.2+ 原生 JSON.SET 是唯一靠谱的 JSON 缓存方式;Redis 本身不存储“JSON 类型”,老版本需字符串序列化,性能差且无结构化操作能力。

Redis 6.2+ 原生 JSON.SET 是唯一靠谱的 JSON 缓存方式
Redis 本身不存储“JSON 类型”,老版本(redis-json 模块(默认内置),才真正支持结构化操作。如果你用的是 6.0 或更早,JSON.SET 直接报错 ERR unknown command `JSON.SET` —— 别折腾,先升级或换方案。
- 确认版本:
redis-cli INFO | grep redis_version,必须 ≥ 6.2 - 部分云 Redis(如阿里云、腾讯云)默认禁用 JSON 模块,需后台开启或选「增强版」实例
- 本地 Docker 启动要加参数:
docker run -d --name redis-json -p 6379:6379 redis:7.0 --loadmodule /usr/lib/redis/modules/rejson.so(7.0+ 已内置,但某些镜像仍需显式加载)
存 JSON 时别用 SET,否则后续所有 JSON.GET 都会失败
用 SET user:1001 "{"name":"Alice","score":95}" 看似能存,但 JSON.GET user:1001 $.name 会返回空或报错 WRONGTYPE Operation against a key holding the wrong kind of value。因为 SET 存的是 string 类型,而 JSON.* 命令只认由 JSON.SET 创建的特殊 JSON 类型 key。
- 正确写法:
JSON.SET user:1001 $ '{"name":"Alice","score":95}'(注意$是根路径,必须写) -
JSON.SET的第三个参数是 JSON 字符串,必须是合法 UTF-8,不能带单引号、不能有 JS 风格的尾逗号 - 如果值是变量(比如 Node.js 的
user对象),务必先JSON.stringify(user),别直接传对象
JSON.GET 的路径语法容易写错,尤其嵌套和数组场景
想取 {"profile":{"tags":["vue","redis"]}} 里的第一个 tag?写成 JSON.GET user:1001 $.profile.tags[0] 才对。写成 $.profile.tags.0 或 $.profile.tags[1](越界)都会返回 null,且不报错——你可能以为数据丢了,其实是路径错了。
- 数组索引必须用方括号:
[0],不是.0 - 通配符
.*可取所有字段值,[*]可取数组所有元素,但性能差,慎用于大数组 - 想判断字段是否存在,用
JSON.TYPE key path,返回string/array/null,比JSON.GET更轻量 - 路径里有空格或特殊字符?用引号包裹:
$.["first name"]
缓存过期得用 EXPIRE 单独设,JSON.SET 不支持 TTL 参数
JSON.SET user:1001 $ '{"name":"Alice"}' EX 3600 是无效语法,Redis 会报错 ERR wrong number of arguments for 'json.set' command。JSON 命令族目前都不支持内建过期,必须分两步:
- 先
JSON.SET user:1001 $ '{"name":"Alice"}' - 再
EXPIRE user:1001 3600 - 这两步非原子操作,若中间 Redis 宕机,可能出现 key 无过期时间的情况;高可靠场景建议用 Lua 脚本封装(
EVAL "redis.call('json.set',KEYS[1],'$',ARGV[1]); redis.call('expire',KEYS[1],ARGV[2])" 1 user:1001 '{"name":"Alice"}' 3600)
另外,JSON.SET 覆盖已有 key 时,原有过期时间会被清除,必须重新 EXPIRE。










