NOSCRIPT 错误是什么
用 EVALSHA 调用脚本时,如果实例缓存里没有这个 SHA1,就会返回 NOSCRIPT No matching script. Please use EVAL。脚本缓存不随重启保留,所以实例重启、滚动升级、执行过 SCRIPT FLUSH 之后的第一批调用最容易撞上它。标准处理是回退用 EVAL 提交脚本体,缓存重建后继续用 EVALSHA。
基本信息
| 错误文本 | NOSCRIPT No matching script. Please use EVAL |
|---|---|
| 触发条件 | 缓存中没有对应 SHA1(重启、清缓存后) |
| 检查命令 | SCRIPT EXISTS <sha1>… |
| 预加载 | SCRIPT LOAD <脚本文本> |
| 客户端处理 | 捕获 NOSCRIPT 后用 EVAL 回退并重建缓存 |
| 集群注意 | 脚本缓存是节点级的,需逐节点预加载或依赖回退 |
典型使用场景
- 实例重启后批量报错:滚动重启期间走 EVALSHA 的调用会失败一次,靠回退自愈
- 发布前预加载:把脚本体当固定资源,启动流程里 SCRIPT LOAD 后拿到 SHA
- 自研客户端加固:确认实现里捕获了 NOSCRIPT 并回退 EVAL
- 集群环境:确认每个分片节点都能命中脚本,或依赖回退兜底
- 排障区分:回退后仍失败说明是脚本体本身的问题,不是缓存问题
最小示例
最小示例
redis-cli SCRIPT EXISTS 5f6b1f9c0f1f... # 检查脚本是否还在缓存
redis-cli SCRIPT LOAD "$(cat script.lua)" # 预加载并得到 SHA1
redis-cli EVALSHA 5f6b1f9c0f1f... 1 mykey # 用 SHA 调用
redis-cli SCRIPT FLUSH # 清空缓存,之后 EVALSHA 会报 NOSCRIPT
redis-cli --cluster call <node:port> SCRIPT LOAD "$(cat script.lua)" # 集群逐节点预加载阶段与现象
| 阶段 | 现象 | 处理 |
|---|---|---|
| 首次调用 | 只有 SHA 没有脚本体 | 用 EVAL 提交一次后缓存建立 |
| 重启后首调用 | 报 NOSCRIPT | 客户端回退 EVAL 重建缓存 |
| 清缓存之后 | 全部 EVALSHA 报错 | 有回退则自动恢复,无回退需人工介入 |
| 集群跨节点 | 其他节点也报 NOSCRIPT | 逐节点预加载,或依赖回退 |
| 脚本体本身有问题 | 回退 EVAL 依然失败 | 属于脚本语法或逻辑问题,与缓存无关 |
主流客户端库都内置了 NOSCRIPT 回退:收到该错误时自动改用 EVAL 提交脚本体。自研客户端必须自己实现这一步。
把脚本体当固定资源管理(版本化、启动时预加载),既能减少首调用失败,也避免动态拼接导致缓存条目无限增长。