Redis 6.2+ 不支持内置cjson,require "cjson"必报错;需手动嵌入精简版cjson.lua实现decode/encode,注意空值处理、性能限制及错误检查。

Redis 6.2+ 内置 cjson 不可用,别白费劲试了
Redis 自身不提供 JSON 编解码函数,即使你用的是 7.0,cjson 也**不会自动加载到 Lua 环境里**。官方 Lua 沙箱明确禁用 require,所以 require "cjson" 会直接报错 error: user_script:1: module 'cjson' not found。别在脚本里写这行,也别指望 Redis 运行时帮你挂载。
必须把 JSON 编解码逻辑“硬编码”进 Lua 脚本
最稳妥的做法是把精简版 cjson 的核心函数(如 encode/decode)以纯 Lua 实现嵌入脚本开头。推荐使用已验证的轻量实现,比如 Redis 官方测试套件中自带的 cjson.lua(注意:它不是运行时模块,而是可复制粘贴的字符串解析器)。
- 只保留
cjson.decode和cjson.encode,删掉所有非必要功能(如流式解析、循环引用检测) - 确保不使用
loadstring或assert—— Redis Lua 沙箱禁用这些 - 嵌入后,调用形如
cjson.decode(ARGV[1]),而非json.decode(后者不存在) - 注意空值处理:
cjson.decode("null")返回nil,而 Redis 命令不能传nil给redis.call,需提前判空
用 redis.call("JSON.SET")?那是 RedisJSON 模块,和 Lua 脚本无关
如果你启用了 RedisJSON 模块,JSON.SET/JSON.GET 是独立命令,可在 Lua 脚本里通过 redis.call 调用,但它**不解决 Lua 内部的 JSON 处理需求**。比如你想在脚本里解析客户端传来的 JSON 字符串做条件判断,还是得靠嵌入的 Lua 解析器。
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
-
redis.call("JSON.SET", "mykey", "$", ARGV[1])可存,但无法对ARGV[1]做字段提取或修改后再存 - 想取
ARGV[1]里的user.id并拼进 key 名?必须先cjson.decode,再取obj.user.id - RedisJSON 返回的是字符串,不是 Lua 表,
redis.call("JSON.GET", "mykey", "$.name")返回"\"Alice\"",还得再 decode 一次才能当字符串用
性能与长度限制:别在 Lua 里解析大 JSON
Redis Lua 脚本有严格的执行时间限制(默认 lua-time-limit = 5000ms)和内存约束。一个 10KB 的 JSON 字符串经 Lua 解析后可能膨胀为数倍内存占用,极易触发 BUSY 错误或被强制中断。
- 单次
cjson.decode建议控制在 1KB 以内,嵌套层级不超过 5 层 - 避免在循环里反复
decode/encode—— 提前解一次,复用结果表 - 如果 ARGV 中 JSON 字段只是用来取一两个字段,考虑让客户端拆解后传原子值(如
ARGV[1] = user_id,ARGV[2] = user_name),绕过解析开销 - 出错时
cjson.decode返回nil, error_msg,务必检查第二返回值,否则后续访问nil.field报attempt to index a nil value
真正麻烦的不是语法,是得自己维护那几百行嵌入的 JSON 解析器代码,并且每次升级 Redis 都得重新核对兼容性 —— 这就是纯 Lua 方案的代价。

















