redis 7.0 移除 script load + evalsha 的传播能力,因其在主从复制中语义不可靠:script load 命令本身不持久化、不复制,从节点无脚本缓存,导致 evalsha 在从节点执行失败或报错,进而引发指令丢失与一致性漏洞。

Redis 7.0 并没有“取消”脚本传播模式设置,而是彻底移除了 SCRIPT LOAD + EVALSHA 的传播控制能力——因为它的语义在主从复制中根本不可靠,且与 AOF 重写逻辑冲突。这不是功能删减,是修复一致性漏洞。
为什么 SCRIPT LOAD 在 Redis 7.0 主从复制中会丢指令
在 Redis SCRIPT LOAD 命令本身不写入 AOF,也不同步到从节点;只有后续的 EVALSHA 才被传播。这就导致:
- 从节点没执行过
SCRIPT LOAD,本地没有该 SHA 对应的脚本,EVALSHA直接报错NOSCRIPT No matching script - 如果主节点 AOF 重写(
bgrewriteaof)发生在SCRIPT LOAD之后、EVALSHA之前,重写后的新 AOF 文件里压根不包含SCRIPT LOAD,从节点重启加载 AOF 时依然缺失脚本 - 即使人工补
SCRIPT LOAD,也无法保证 SHA 一致(不同版本 Lua 解析器或编译选项可能导致 SHA 变化)
redis.function 如何从根源解决传播问题
Redis Functions 要求函数必须通过 FUNCTION LOAD 显式注册,并且该命令强制写入 AOF、强制同步到所有从节点。关键点在于:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
FUNCTION LOAD是原子写操作:脚本内容 + 元数据(库名、函数名、ACL 权限)全部落盘并复制,不存在“只传 SHA 不传体”的断层 - 函数版本号内置于注册流程,
FUNCTION FLUSH或FUNCTION DELETE也会被完整记录,AOF 重写时能准确重建函数状态 - 从节点加载 AOF 时,遇到
FUNCTION LOAD就立即注册,后续任何FCALL都能命中,不再依赖客户端缓存或执行顺序
你还在用 EVAL?这些坑在 7.0 里更隐蔽
虽然 EVAL 仍可用,但它在 Redis 7.0 的 AOF 和复制链路中已被降级为“尽力而为”模式:
-
EVAL脚本体直接写入 AOF,但若脚本过大(默认超proto-max-bulk-len限制),AOF 写入可能失败并截断,导致从节点加载失败 - 主节点内存中缓存的脚本 SHA 不同步,从节点无法复用,每次
EVAL都要重新解析,CPU 开销翻倍 - ACL 权限无法按函数粒度控制:
EVAL总是继承调用者的权限上下文,而FUNCTION LOAD可绑定指定 ACL 规则
真正需要关注的不是“怎么迁移到 Functions”,而是确认你的业务是否隐式依赖了旧版脚本的松散传播行为——比如靠客户端重试 SCRIPT LOAD 来兜底。这种逻辑在 7.0+ 环境下会静默失效,且错误只在从节点重启或 AOF 重写后暴露。










