FCALL是Redis 7.0架构级替代EVAL的函数调用命令,无需传输脚本、跳过编译、自带可观测性与ACL细粒度权限控制,函数名须带库前缀(如inventory.decr_stock),且Lua环境收紧需显式声明redis和keys参数。

FCALL 不是 EVAL 的“语法糖”,而是架构级替代:它省掉网络传输、编译和缓存管理开销,且自带可观测性与权限隔离。
FCALL 调用函数时不需要传脚本内容
EVAL 每次执行都要把整段 Lua 代码通过网络发给 Redis,哪怕脚本只有几行;FCALL 只需传函数名和参数,比如 FCALL inventory.decr_stock 1 item:123 10。服务器端已预加载函数定义,跳过了字符串解析、语法检查、字节码编译三步——这对高频调用(如库存扣减)意味着毫秒级延迟下降。
- Redis 7.0 启动时或通过
FUNCTION LOAD加载的函数,会持久化在内存中,不随故障转移丢失(对比 EVAL 的脚本缓存在主节点上,failover 后副本无脚本) - 客户端不再需要维护
SCRIPT LOAD+EVALSHA的 fallback 逻辑,也不用处理NOSCRIPT错误重试 - 注意:函数名必须带库前缀,如
inventory.decr_stock,不能只写decr_stock;否则报错ERR unknown function
FUNCTIONS 支持库级版本管理和 ACL 权限控制
EVAL 是全功能 Lua 执行环境,ACL 只能按命令粒度开关(如禁用 EVAL 就全禁),而 FUNCTIONS 允许你对每个函数单独授权:ACL SETUSER alice ~inventory.* +@function 表示用户 alice 只能调用 inventory 库下的函数。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
FUNCTION LIST查看所有已加载函数及其 SHA256 校验值,FUNCTION LIST WITHCODE还能导出源码,方便审计和迁移 - 函数库不支持单点热更新,改一个函数就得用
FUNCTION FLUSH+FUNCTION LOAD重载整库,避免运行中版本错乱 - 别混淆
SCRIPT KILL和FUNCTION KILL:后者只终止正在运行的函数实例,且仅对阻塞型函数(如含redis.call("sleep", 1000))有效
从 EVAL 迁移到 FCALL 容易踩的 Lua 环境坑
Functions 对 Lua 沙箱做了收紧:默认禁用全局变量访问,redis 表不可直接调用,KEYS 和 ARGV 也不再是全局数组,必须显式声明为函数参数。
- 老 EVAL 脚本里写
redis.call("incr", KEYS[1])会报错attempt to call a nil value (global 'redis') - 正确写法是函数体开头加
local redis = redis(Redis 自动注入),并用redis.call("incr", keys[1]),注意keys小写、索引从 1 开始 - 函数定义里必须明确标注 key 参数个数,比如
FCALL inventory.decr_stock 1 item:123 10中的1表示第一个参数item:123是 key,后续10是 arg —— 错位会导致ERR wrong number of arguments
真正麻烦的不是语法转换,而是函数库的部署节奏:不同业务线可能共用一个 Redis 实例,但函数库是全局命名空间,FUNCTION LOAD 会覆盖同名库;上线前得协调好加载顺序,别让 A 团队的 inventory 库把 B 团队的覆盖掉。


















