当前位置:首页 > 文章列表 > 数据库 > Redis > Redis Functions 怎样加载可重复调用的服务端函数

Redis Functions 怎样加载可重复调用的服务端函数

来源:17golang原创 2026-10-29 00:21:08 0浏览 收藏

如果一段 Lua 逻辑需要被多个请求反复调用,Redis Functions 的做法是先把“库”加载到 Redis,再用函数名调用,而不是每次把完整脚本重新发过去。最小闭环只有三件事:源码以 #!lua name=库名 开头,库内通过 redis.register_function 注册入口,加载后用 FCALL 函数名 numkeys ... 调用。

官方地址:https://redis.io/docs/latest/develop/programmability/functions-intro/

本文只围绕“怎样加载并重复调用一个服务端函数”展开。下面的命令和输出是用于说明语义的示例,不代表在本文环境中实际运行过。

先判断:应该加载库,还是每次发送脚本

Redis 7 引入的 Functions 把函数作为数据库管理的服务端工件。相比每次用 EVAL 发送脚本,调用方只依赖函数 API;库可以包含多个函数,库名和函数名也比一串 SHA 更容易在排查时识别。

方式代码在哪里适合的调用形态
EVAL客户端请求里临时执行一次脚本
EVALSHARedis 脚本缓存里客户端维护脚本并重复调用
Redis FunctionsRedis 的函数库里先部署库,再由多个调用方按函数名重复使用

选择 Functions 后,第一步不是直接写 FCALL,而是先准备一个可加载的 library。空库会失败,因为 Redis 要求库至少注册一个函数。

一份能加载的最小 Lua 库

下面的库名是 orderlib,函数名是 mark_order。它接收一个订单 key 和一组普通参数,把状态写入 Hash。示例特意把 key 与普通参数分开,后面调用 FCALL 时就能看出 numkeys 的作用。

#!lua name=orderlib

-- 注册一个需要一个 Redis key 的服务端函数。
local function mark_order(keys, args)
  -- keys[1] 必须来自 FCALL 的 key 区域,不能把它当普通参数传入。
  if #keys ~= 1 then
    return redis.error_reply('mark_order requires exactly one key')
  end

  -- 普通参数按顺序放在 args 中:字段名和值各占一个位置。
  if #args ~= 2 then
    return redis.error_reply('mark_order requires field and value')
  end

  return redis.call('HSET', keys[1], args[1], args[2])
end

-- 只有注册后的名字才能通过 FCALL 找到这个函数。
redis.register_function('mark_order', mark_order)

其中 Shebang 的 name=orderlib 是库名,不是函数名;mark_order 才是之后传给 FCALL 的入口名。一个库可以注册多个函数,但它们会随库一起加载和更新。

Redis Functions 库名、Lua 源码、注册函数、key 参数和普通参数之间的静态关系说明图
图1:Redis Functions 库结构说明图,展示库名、注册函数、key 区域和普通参数的静态关系;这是说明图,不是运行截图。

用 FUNCTION LOAD 首次加载,用 REPLACE 整库更新

Redis 的命令语法是 FUNCTION LOAD [REPLACE] function-code。如果源码保存为 orderlib.lua,可以把整个文件通过标准输入交给 redis-cli -x:

# 首次把完整 Lua 库交给 Redis;-x 让 redis-cli 从标准输入读取库源码。
cat orderlib.lua | redis-cli -x FUNCTION LOAD

# 修改库内任意函数后,使用 REPLACE 以整库为单位替换旧定义。
cat orderlib.lua | redis-cli -x FUNCTION LOAD REPLACE

首次加载成功时,返回值是库名 orderlib。如果同名库已经存在而没有写 REPLACE,Redis 会拒绝本次加载;REPLACE 不是只替换一个函数,而是用新的完整库定义覆盖旧库,所以发布时应把库内所有函数一起纳入版本管理。

orderlib
(error) ERR Library 'orderlib' already exists
orderlib

不要把返回的库名误当成函数调用名。加载成功只是说明库被接受,真正调用仍要传入已注册的函数名。

用 FCALL 调用:numkeys 决定参数分区

这个例子里函数只需要一个 key,因此 numkeys 写成 1:

# 1 表示后面的第一个参数是 key;其余两个参数是普通参数。
redis-cli FCALL mark_order 1 order:100 status paid

# 读取刚才由函数写入的字段,用于理解返回值语义。
redis-cli HGET order:100 status
(integer) 1
paid

Redis 会把 order:100 放进 Lua 回调的 keys 表,把 status 和 paid 放进 args 表。如果把 numkeys 写成 0,函数内部的 keys 就为空;如果写成 2,第二个参数也会被当成 key。这个数字不是“参数总数”,而是 key 参数的数量。

在 Redis Cluster 中,函数访问的所有 key 都必须显式出现在 key 区域,并且同一次调用的 key 要满足集群的路由约束。不要把 key 拼在普通参数里来绕过这个边界。

FCALL 的函数名、numkeys、Redis key、普通参数和函数返回值之间的静态边界说明图
图2:FCALL 参数边界说明图,展示 numkeys 如何把输入分成 keys 与 args;这是结构图,不是运行截图。

加载完成后怎样判断没有走错

可以按“库—函数—调用参数”三个层次判断。先用 FUNCTION LIST 查看库名和已注册函数,再用一次最小 FCALL 检查函数名与 key 数量是否一致:

# 列出服务端已加载的库和函数元数据。
redis-cli FUNCTION LIST

# 本例的 mark_order 会写 Hash,所以使用普通 FCALL。
redis-cli FCALL mark_order 1 order:100 status shipped

排查时重点看这几类结果:

  • 返回 ERR No functions registered:库源码只有 Shebang,没有调用 redis.register_function。
  • 返回“库已存在”:首次加载命令重复执行,确认是否应该使用 REPLACE。
  • 函数报 key 数量错误:检查 FCALL 的 numkeys,不要先改 Lua 逻辑。
  • 集群只有部分节点能找到函数:Redis Cluster 需要由管理员把库加载到所有 master 节点;副本传播不等于集群所有 master 自动完成部署。

Redis Functions 的执行仍然是原子的,并会在执行期间阻塞服务器处理其他活动,因此函数应保持短小,不能把长时间计算或等待外部资源的工作塞进一次函数调用。

常见问题

FUNCTION LOAD 返回的是函数名吗?

不是。成功返回加载的库名;函数名来自 redis.register_function,之后由 FCALL 使用。

修改一个函数时能否只上传这个函数?

不能把库当成可选择更新的函数集合。Redis Functions 以库为更新单位,使用 FUNCTION LOAD REPLACE 时应提交包含全部注册函数的完整库源码。

总结一下:先用带 Shebang 的 Lua 源码注册函数,再用 FUNCTION LOAD 首次加载、用 REPLACE 更新整库,最后通过正确的 numkeys 把 key 与普通参数分开传给 FCALL。这样库的部署动作和业务调用动作就能清晰分离。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Redis SETRANGE 超出原长度为什么会补零字节Redis SETRANGE 超出原长度为什么会补零字节
上一篇
Redis SETRANGE 超出原长度为什么会补零字节
VS Code 怎样把多根工作区保存为项目文件
下一篇
VS Code 怎样把多根工作区保存为项目文件
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    761次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    758次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    842次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    810次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    641次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码