开发人员可以使用Redis来构建和维护实时应用程序。您可以创建 JavaScript 函数,直接在 Redis 数据库中自动执行数据更改代码,从而确保较低的延迟。
一般来说,应用程序处理业务逻辑操作,将执行代码发送到数据库。这是一个缓慢的过程,因为每次执行函数时代码都会从客户端流入服务器。开发人员负责维护访问同一数据库的所有应用程序之间的代码一致性,无论代码是简单的请求还是复杂的数据操作,而且很多时候代码会在应用程序之间重复。
遵循 Redis 宣言的指导方针:我们反对复杂性,我们必须采取行动并找到应对这些挑战的解决方案。
四年前,我们推出了 RedisGears,这是我们平台内的第一个可编程模型。开发人员在数据所在的地方编写并执行脚本。然而,脚本是短暂的,由每个客户端提供,这可能会导致不一致。
沿着这个方向,在 Redis 7.0 中,我们引入了带有函数的脚本方法的初始实现。函数提高了可用性和持久性,因为它们是数据库的一部分,继承了数据的复制和持久性级别。
现在,我们很自豪地展示可编程性的下一步。在 Redis 7.2 中,我们引入了触发器和函数。这些增强了 Redis 的可编程性,扩展了服务器端功能,改进了数据库中执行功能的方式和时间,并促进了直接在数据所在的地方执行复杂的业务逻辑。
触发器和函数的基础知识
触发器和函数是通过 Redis Stack 提供的新一代可编程性。它允许开发人员直接在 Redis 数据库中针对数据更改进行编程、存储和自动执行 JavaScript 代码。
此功能允许开发人员定义事件(称为触发器)来执行更接近数据的函数。也就是说,开发人员定义响应数据库事件或命令而执行的业务逻辑。这加快了代码和相关交互的速度,因为无需等待即可将代码从客户端引入数据库。
它还加快了对 Redis 中其他事件的反应时间,例如未通过发布和订阅(Pub/Sub) 事件等其他方式实时处理的键空间通知。
触发器和函数处理集群数据库内的分布,在每个分片上安装库并根据密钥所在的位置执行函数。
我们还推出了远程功能。远程函数允许您执行读取操作,这些操作可以从任何槽访问数据,甚至在集群数据库中也是如此,因此可以从每个函数访问所有数据。
它使用最流行的编程语言 JavaScript
Redis 使用 Lua 来编写脚本和函数。Lua有很多好处,例如代码可重用性,但它并不是专业开发人员中常用的语言。根据2022 年 StackOverflow 开发者调查,只有 3.2% 的开发者以专业身份使用 Lua。
相比之下,三分之二的开发人员使用 JavaScript。使用众所周知的语言可以降低新 Redis 开发人员的采用障碍。又少了一件需要学习的事情。
应用程序代码更容易支持和维护
触发器和函数的另一个好处是它降低了跨多个应用程序管理业务逻辑的复杂性。
当多个应用程序访问同一数据库时,开发人员必须协调应用程序如何以一致的方式处理数据。在每个应用程序中复制代码以验证数据、丰富搜索结果或在另一个应用程序进行更改时更新数据库是很常见的。
借助触发器和函数,不再需要在多个应用程序上重复代码。代码始终以相同的方式执行,按需执行或由数据库中的事件启动。
数据库事件实时处理
到目前为止,对 Redis 中的数据库事件做出反应需要开发人员依赖 Pub/Sub 机制。虽然 Pub/Sub 有很多优点,但它并不总是正确的选择。特别是,Pub/Sub 不是实时的。客户端必须主动监听事件;如果客户端没有监听,事件就会丢失。
现在,开发人员可以注册基于键前缀和事件类型执行的键空间触发器。触发器可以以原子方式执行,以便在事件和业务逻辑之间不处理其他 Redis 事件。
告诉我它是如何完成的
通过实际的例子总是更容易理解事情。这里,我们介绍注册一个函数和一个触发器。当通过 TFCALL 命令调用函数时,函数就会被执行;触发器根据 Redis 中的事件执行。
序言定义我们使用js引擎,库名称为lib,所需的触发器和函数API的最低版本为1.0。
#!js name=lib api_version=1.0接下来,我们创建一个返回 Redis 命令结果的函数。客户端允许在我们的函数中执行 Redis 命令。数据事件包含运行函数时可以提供的键和参数。
function answer(client, data) {
return client.call(“ping”);
}Redis 全局变量允许您注册触发器和函数,并记录到日志文件。我们使用名称注册该函数,并在函数执行时调用该名称。
redis.registerFunction(‘playPingPong’, answer);完整的 JavaScript 文件如下所示。
#!js name=lib api_version=1.0
function answer(client, data) {
return client.call(‘ping’);
}
redis.registerFunction(‘playPingPong’, answer);将其另存为 lib.js.
然后我们使用命令在触发器和函数中注册我们的函数TFUNCTION LOAD。该TFUNCTION LOAD命令还将库分发到集群数据库中。
> redis-cli -x TFUNCTION LOAD < ./lib.js
OK现在我们可以使用 TFCALL 命令执行该函数。该命令获取以句点分隔的库名称和函数名称。
>redis-cli TFCALL lib.playPingPong 0
“PONG”这样,您就成功地在 Redis 数据库中创建、注册并触发了一个函数。
我们可以使用键空间触发器扩展这个示例。我们添加了一个新的注册,该注册对前缀为 的键做出反应'fellowship:'。在文件末尾添加此代码lib.js。
function addLastUpdatedField(client, data) {
if(data.event == ‘hset’) {
var currentDateTime = Date.now();
client.call(‘hset’, data.key, ‘last_updated’, currentDateTime.toString());
}
}
redis.registerKeySpaceTrigger(‘addLastUpdated’, 'fellowship:', addLastUpdatedField);使用TFUNCTION LOAD带有REPLACE参数的命令来更新现有库。该TFUNCTION LOAD REPLACE命令立即更新所有使用 Redis 数据库的客户端,并且它们开始使用新的业务逻辑。
>redis-cli -x TFUNCTION LOAD REPLACE . < ./lib.js
OK要测试新的键空间触发器,请创建一个以 Fellowship: 开头的新键,并使用 RedisInsight 检查字段。keyspace触发器是通过命令执行的,因此在创建key时已经添加了last_updated字段。

听起来很酷吗?亲自尝试一下
加入 Redis Stack 7.2 触发器和函数的公共预览版。通过在 Google Cloud/亚太地区(东京)或 AWS/亚太地区(新加坡)区域的固定层中的Redis Enterprise Cloud上创建数据库,开始在云中使用 Redis Stack ,或者从我们的下载中部署自我管理实例中心.
计划在 Redis 8 中全面推出触发器和函数。这将包括从预览版用户收到的反馈,以及附加功能,例如定时触发器和更多调试选项。
欢迎在Redis 邮件列表上提出评论和反馈。
文章来源:https://redis.com/blog/introducing-triggers-and-functions/




