Redis 7.0 引入 Redis Functions 作为 Lua 脚本的演进方案,迁移旧代码需将 `EVAL` 逻辑封装为库并使用 `FUNCTION LOAD` 部署。适用场景为需要版本管理和长期复用的逻辑,风险边界是不兼容 Redis 7.0 以下版本且禁止使用非确定性原生 Lua 命令。
先说结论:迁移本质是代码封装标准化和调用命令替换,非单纯性能优化。
- 适合:需要服务端持久化存储、版本管理的脚本逻辑
- 先看:原脚本是否包含 `math.random` 或 `redis.call('TIME')` 等非确定性调用
- 建议:先在测试环境验证 `FUNCTION LOAD` 加载成功率再全量切换
命令速用版
旧版 Lua 脚本使用 `EVAL` 直接执行代码,Redis Functions 使用 `FUNCTION LOAD` 加载库后通过 `FUNCTION CALL` 调用。以下是对比示例:
# 旧版 Lua 脚本执行
EVAL "return redis.call('GET', KEYS[1])" 1 key1
# 新版 Redis Functions 加载
FUNCTION LOAD REPLACE "#lua
redis.register_function('my_get', function(keys, args)
return redis.call('GET', keys[1])
end)
"
# 新版 Redis Functions 调用
FUNCTION CALL my_get 1 key1为什么会这样
Redis Functions 解决了 Lua 脚本难以版本管理和重复加载的问题。旧版 Lua 脚本通常作为临时代码发送,服务端不持久化存储逻辑本身,而 Redis Functions 将代码作为库注册在服务端状态中,支持命名空间、版本替换和内存统计。官方文档指出 Functions 旨在提供更安全的沙箱环境和更好的可观测性。
分步处理
迁移旧代码需按以下步骤操作,确保逻辑一致且符合新规范。
第一步:代码封装
将原有 Lua 脚本逻辑包裹在 `redis.register_function` 中,并指定函数名。原 `KEYS` 和 `ARGV` 分别对应新函数的 `keys` 和 `args` 参数表。
第二步:兼容性检查
检查脚本中是否使用了非确定性命令。原生 Lua 的 `math.random` 需改为 `redis.random`,获取时间需使用 `redis.time()` 而非 `redis.call('TIME')`,以确保复制一致性。
第三步:加载与替换
使用 `FUNCTION LOAD REPLACE` 命令加载代码。`REPLACE` 参数允许覆盖同名库,适合更新逻辑。加载成功后服务端会返回库名称。
第四步:调用切换
客户端代码将 `EVAL` 命令改为 `FUNCTION CALL`。第一个参数为函数名,第二个参数为 keys 数量,后续依次为 keys 和 args。
怎么验证是否生效
加载后可通过以下命令确认函数状态和执行情况。
检查函数列表:
FUNCTION LIST返回结果应包含已加载的库名和函数名,确认 `description` 和 `flags` 符合预期。
检查运行统计:
FUNCTION STATS查看 `running_script` 字段确认是否有函数正在执行,或通过日志观察调用延迟。
功能回归测试:
使用相同输入参数分别运行旧 `EVAL` 脚本和新 `FUNCTION CALL` 函数,比对返回值是否完全一致。
常见坑
- 版本兼容性:Redis Functions 仅在 Redis 7.0 及以上版本支持,混合部署环境需确认所有节点版本。
- 非确定性命令:直接使用 `math.random` 会导致主从复制数据不一致,必须使用 Redis 提供的 API。
- 内存限制:函数库代码计入 Redis 内存,过大代码块可能触发内存淘汰策略,建议保持逻辑精简。
- 参数传递:旧脚本 `KEYS` 表索引从 1 开始,新函数 `keys` 表索引同样从 1 开始,但需确保 `FUNCTION CALL` 命令中 keys 数量参数准确。
常见问题
Redis 7.0 后还能继续使用 EVAL 吗?
可以继续使用。Redis Functions 是新增特性,并未移除 `EVAL` 命令,旧 Lua 脚本仍可正常运行,但建议新逻辑优先使用 Functions。
迁移后性能会有提升吗?
公开资料中没有看到可靠的量化数据表明 Functions 比 Lua 脚本执行更快。主要优势在于管理性和可观测性,而非运行时性能。
函数库代码会持久化吗?
会。函数库作为服务器状态的一部分,会随 RDB 快照和 AOF 日志持久化,重启后无需重新加载。
参考来源
- Redis Documentation, "Redis Functions", https://redis.io/docs/latest/develop/interact/programmability/functions-intro/
- Redis GitHub, "Redis 7.0.0 Release Notes", https://github.com/redis/redis/releases/tag/7.0.0