一、背景与动机

传统的 Redis 脚本机制依赖于客户端加载 EVAL 脚本,存在以下局限:

  1. 网络与编译开销
    每次调用都要传输脚本源码或重新加载 SHA1。
  2. 缓存失效风险
    重启、主从切换、SCRIPT FLUSH 后脚本缓存丢失,事务易失败。
  3. 调试与运维困难
    SHA1 不可读、难以在 MONITOR 或日志中追踪。
  4. 代码复用受限
    脚本之间无法互相调用,只能由客户端拼接多份代码。

Redis Functions 应运而生,将脚本纳入 Redis 数据模型,以「声明—持久化—调用」的方式,提供了更高效、更可靠、更易运维的服务器端脚本化能力。

二、Redis Functions 概览

  • 第一类工件
    函数(Function)属于数据库自身的组成部分,随数据持久化(AOF/RDB)与复制而同步。

  • 库(Library)管理
    多个函数组织在同一库中,整体加载或替换,不支持单个函数增量更新。

  • Shebang 元数据
    通过 #!<engine> name=<library> 指定执行引擎与库名称。

  • 调用接口

    • FUNCTION LOADFUNCTION DELETEFUNCTION LIST 管理库
    • FCALL(可写)或 FCALL_RO(只读)执行函数

三、加载与注册函数库

  1. 编写库源码
    以 Lua 为例,库文件开头必须包含 Shebang 行:

    #!lua name=mylib
    
  2. 注册函数
    通过 redis.register_function(name, callback, [flags]) 将每个函数注册到库中:

    redis.register_function('knockknock',function() return "Who's there?" end
    )
    
  3. 加载到 Redis

    cat mylib.lua | redis-cli -x FUNCTION LOAD REPLACE
    

    返回值为库名(如 mylib),表示加载成功。

四、调用函数:FCALL 与 FCALL_RO

  • FCALL [keys…] [args…]
    在任何节点执行(可写)。
  • FCALL_RO [keys…] [args…]
    只读副本上执行,只允许标记为 no-writes 的函数。

示例调用:

redis> FCALL knockknock 0
"Who's there?"

五、键名与参数

  • KEYS:指定所有将要访问的 Redis 键名,必须在调用时列出,保证集群模式下数据访问的正确路由。
  • ARGV:所有非键名输入,供函数内部业务逻辑使用。

在函数回调中,Lua 参数形式为:

function(keys, args)-- keys 是一个 Lua 数组,包含前 numkeys 个参数-- args 是包含后续所有普通输入的数组
end

六、示例:可复用的 Hash 操作库

下面以一个「自动记录最后修改时间」的 Hash 操作库为例,演示如何在同一库中组织多个函数并实现代码复用。

#!lua name=mylib-- 辅助:校验 keys 数量
local function check_keys(keys)if #keys ~= 1 thenreturn redis.error_reply("只允许传入一个键名")endreturn nil
end-- my_hset:设置字段并记录时间戳
local function my_hset(keys, args)local err = check_keys(keys)if err then return err endlocal hash = keys[1]local ts = redis.call("TIME")[1]return redis.call("HSET", hash, "_last_modified_", ts, unpack(args))
end-- my_hgetall:读取所有字段(排除 _last_modified_)
local function my_hgetall(keys, args)local err = check_keys(keys)if err then return err endredis.setresp(3)  -- 切换到 RESP3,返回字典格式local hash = keys[1]local res = redis.call("HGETALL", hash)res.map["_last_modified_"] = nilreturn res
end-- my_hlastmodified:读取修改时间戳
local function my_hlastmodified(keys, args)local err = check_keys(keys)if err then return err endreturn redis.call("HGET", keys[1], "_last_modified_")
end-- 注册函数,并为只读函数添加 no-writes 标志
redis.register_function("my_hset",    my_hset)
redis.register_function{function_name = "my_hgetall",callback      = my_hgetall,flags         = {"no-writes"}
}
redis.register_function{function_name = "my_hlastmodified",callback      = my_hlastmodified,flags         = {"no-writes"}
}

加载并调用:

cat mylib.lua | redis-cli -x FUNCTION LOAD REPLACE
redis> FCALL my_hset 1 myhash field1 "value1"
(integer) 2redis> FCALL_RO my_hgetall 1 myhash
1) "field1"
2) "value1"redis> FCALL_RO my_hlastmodified 1 myhash
"1640772721"

七、集群与持久化

  • 复制与持久化
    函数与数据一同写入 AOF/RDB,并复制到从节点,保证函数持久可用。
  • 集群加载
    需要在所有主节点执行 FUNCTION LOAD,可借助 redis-cli --cluster-only-masters 批量操作。
  • RDB 钩子
    使用 redis-cli --functions-rdb 可导出函数的 RDB 文件,在启动时预加载到新的实例。

八、函数标志与权限控制

  • 默认行为
    Redis 假定所有函数可能读写数据,故禁止在只读场景(FCALL_RO 或只读副本)下执行。
  • no-writes 标志
    redis.register_function 时添加 flags={'no-writes'},表明函数仅执行读操作,允许在只读场景下调用。
  • 更多 Flags
    请参见官方文档 Script flags,设置合适权限确保安全与隔离。

九、最佳实践与注意事项

  1. 避免长时间阻塞
    函数执行时会阻塞主线程,应保持逻辑简短,避免慢查询或大批量数据扫描。
  2. 键名列举全
    集群模式下访问所有键必须列出于 numkeys 参数,防止跨槽错误。
  3. 整体替换
    函数库更新时会替换全量代码,确保所有函数均在同一版本下协同工作。
  4. 日志与监控
    可在函数内部调用 redis.log() 输出警告或错误,便于生产环境诊断。
  5. 版本管理
    建议将函数库源码纳入版本控制,与应用一并发布,保持部署可追溯。

十、总结

Redis Functions 通过将服务器端脚本化提升为第一类工件,彻底解决了 EVAL 脚本在分发、缓存、调试和复用上的痛点。它不仅让脚本管理更可靠,也让 Redis 能像模块一样对外提供统一 API,助力构建更复杂、更高效的业务逻辑。结合本文示例和最佳实践,相信你能快速上手 Redis 7+ 的函数特性,并在生产环境中获得显著的运维与性能收益。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912997.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912997.shtml
英文地址,请注明出处:http://en.pswp.cn/news/912997.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java项目:基于SSM框架实现的云端学习管理系统【ssm+B/S架构+源码+数据库+毕业论文】

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对课程学习信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差…

【压力测试之_Jmeter链接Oracle数据库链接】

Oracle数据库链接 欢迎来到挖坑避坑课堂链接数据库 欢迎来到挖坑避坑课堂 之前性能测试都是业务之类的&#xff0c;数据库压测很少涉及&#xff0c;就会出现很多各式各样的问题&#xff0c;首要问题就是Jmeter链接数据库的问题&#xff0c;本篇主要讲解Jmeter链接Oracle数据库…

Appium与Appium Inspector配置教程

一、连接设备 首先将手机的开发者模式打开&#xff0c;不同手机的开启方法不同&#xff0c;这里演示的测试机为vivoS1&#xff0c;其他机型的开启方法大家可以自行AI搜索。 1.手机授权 &#xff08;1&#xff09;点击手机的【设置】选项 &#xff08;2&#xff09;打开手机…

【web出海】深度拆解 FLUX.1 kontext:这不仅是AI绘画的革命,更是 MicroSaaS 创业者的黄金机遇

前言 近日&#xff0c;Black Forest Labs 发布的 FLUX.1 Kontext 模型在AI圈掀起了波澜。它不仅仅是又一个文生图工具&#xff0c;其独特的“在情境中&#xff08;in-context&#xff09;”编辑、惊人的角色一致性、精准的局部修改和强大的文字渲染能力&#xff0c;标志着一个技…

Git 安装闭坑指南(仅 Windows 环境)

&#x1f4bb; Git 安装闭坑指南&#xff08;仅 Windows 环境&#xff09; 适用人群&#xff1a;刚开始用 Git 的 Windows 用户&#xff1b;重新配置开发环境的程序员&#xff1b;不想踩坑的团队小伙伴 目标&#xff1a;快速、稳定地安装 Git&#xff0c;在各种常见场景下避免“…

2025年4月SCI-吕佩尔狐优化算法Rüppell’s fox optimizer-附Matlab免费代码

引言 本期介绍一种新的元启发式算法——吕佩尔狐优化算法Rppell’s fox optimizer&#xff0c;RFO。RFO的灵感来自于吕佩尔狐狸在白天和晚上自然而聪明的集体觅食行为。优化器利用吕佩尔狐敏锐的视觉、听觉和嗅觉对其各种主要觅食活动进行数学模拟&#xff0c;在优化过程中兼顾…

SwiftUI 中的模糊效果详解:.blur、.material、UIVisualEffectView

模糊效果&#xff08;Blur Effect&#xff09;是 iOS 用户界面设计的重要组成部分&#xff0c;它被广泛应用于系统控制中心、通知背景、弹窗蒙版等场景&#xff0c;营造出“毛玻璃”的视觉层次感。 本文将深入解析 SwiftUI 中实现模糊效果的三种主流方式&#xff1a;.blur(radi…

Euler2203安装.NetCore6.0环境操作步骤

# 1. 下载.NET二进制包 wget https://download.visualstudio.microsoft.com/download/pr/xxxx/dotnet-sdk-6.0.xxx-linux-x64.tar.gz把dotnet-sdk-6.0.428-linux-x64.tar.gz放到一个目录里面# 2. 创建安装目录sudo mkdir -p /usr/share/dotnetsudo tar -zxf dotnet-sdk-6.0.428…

解决安装SunloginClient问题记录(Ubuntu 24.04.2)

成功安装流程&#xff08;Ubuntu 24.04.2&#xff09; 1. 首次尝试安装&#xff08;失败&#xff0c;缺少依赖&#xff09; sudo dpkg -i ./SunloginClient_15.2.0.63064_amd64.deb sudo apt-get install -f # 修复依赖&#xff08;此时提示缺少 libgconf-2-4&#xff09; …

wordpress安装教程

一、安装软件 1、apache sudo apt install apache2 -y 2、mysql sudo apt install mysql-server -y 3、PHP及其扩展 sudo apt install php libapache2-mod-php php-mysql php-curl php-gd php-mbstring php-xml php-xmlrpc php-soap php-intl php-zip php-fpm -y 重启ap…

C#,VB.NET从JSON数据里提取数组中的对象节点值

在VB.NET中&#xff0c;若要从 JSON 数据里提取Data.DataList数组中的CategoryId&#xff0c;并将其转换为VB.NET数组&#xff0c;可借助Json.NET&#xff08;Newtonsoft.Json&#xff09;库来实现。下面为你详细介绍具体的实现步骤和代码示例&#xff1a; 一、实现 JSON 到数…

Flutter 进阶:实现带圆角的 CircularProgressIndicator

在 Flutter 中&#xff0c;我们经常使用 CircularProgressIndicator 来展示加载进度。但是你是否注意到&#xff1a;它的进度端始终是“平头”的&#xff08;直角&#xff09;&#xff1f; 这在一些 UI 设计中并不美观&#xff0c;特别是想实现类似 Apple 健身环那样“前端圆清…

解决CentOS7下载docker-compose出现没有可用软件包问题

1 问题描述 今天在使用虚拟机CentOS 7系统安装docker-compose时&#xff0c;用的是aliyun镜像&#xff0c;出现没有可用软件包的问题&#xff0c;这就说明不是因为网络&#xff0c;而是因为aliyun镜像没有该软件包。 2 解决办法 这里推荐最稳定的解决办法&#xff0c;去docker-…

基于SpringBoot+Vue的酒类仓储管理系统

文档包含用例图、系统架构图、系统功能结构图、实体属性图、总体e-r图。一.系统开发工具与环境搭建1.系统设计开发工具后端使用Java编程语言的Spring boot框架项目架构&#xff1a;B/S架构运行环境&#xff1a;win10/win11、jdk17前端&#xff1a;技术&#xff1a;框架Vue.js&a…

月付物理服务器租用平台-青蛙云

青蛙云物理服务器租用服务概述 青蛙云是一家提供物理服务器租用服务的平台&#xff0c;支持月付、年付等灵活付费方式&#xff0c;物理服务器适合企业或个人用户的高性能计算需求。其服务覆盖多地区机房&#xff0c;提供多种配置选项&#xff0c;支持定制化需求。 核心优势 …

基于二分类方法和安全系数方法使用comsol with matlab蒙特卡洛模拟实现边坡失效概率计算——随机变量模型

基于二分类方法和安全系数方法使用comsol with matlab蒙特卡洛模拟实现边坡失效概率计算——随机变量模型 模型和全部代码下载随机变量模拟加载comsol模型蒙特卡洛模拟(分类模型)蒙特卡洛模拟(安全系数模型)内聚力和内摩擦角随机变量分布二分类稳定性1000次运行结果失效概率…

机器学习-02(深度学习的基本概念)

机器学习的步骤 1.定义带有未知参数的函数 线性模型&#xff08;linear models&#xff09;具有较大的限制&#xff08;Model Bias&#xff09; y b wx 无论如何更改b或者w&#xff0c;其只会呈现出一条直线&#xff0c;不能满足更加复杂的现实情况。 我们可以将复杂的函…

InspireFace C++ 架构分析

InspireFace C 架构分析 https://github.com/deepinsight/insightface/tree/master/cpp-package/inspireface 1. 项目概述 InspireFace 是一个高性能的人脸识别和分析 SDK&#xff0c;采用 C 开发&#xff0c;提供了完整的人脸检测、跟踪、特征提取、活体检测、属性分析等功…

【网络安全】Webshell命令执行失败解决思路

前言费尽心思上传了webshell&#xff0c;上传下载都没问题&#xff0c;却发现命令执行总是失败&#xff1f;最近也打点也遇到了这些问题&#xff0c;网上有部分文章&#xff0c;但都是零碎知识点并且实战不一定能用&#xff0c;今天就结合我个人经验剖析webshell上线后cmd命令执…

【机器人】复现 HOV-SG 机器人导航 | 分层 开放词汇 | 3D 场景图

HOV-SG 是通过语言指令实现机器人导航的&#xff0c;核心特点是分层结构、开放词汇、3D场景图。 来自RSS 2024&#xff0c;大规模、多层次的环境构建精确的、开放词汇的3 场景图&#xff0c;并使机器人能够通过语言指令在其中有效地导航。 论文地址&#xff1a;Hierarchical …