集群支持
触发器和函数的集群支持
Redis 开源 | Redis 企业版软件 | Redis Cloud | Redis 开源 | Redis 企业版 for Kubernetes | 客户端 |
---|
注意:在 Redis 开源集群上,在执行任何 gears 函数之前,必须将 REDISGEARS_2.REFRESHCLUSTER
命令发送到所有分片,以便它们了解集群拓扑。 如果没有此步骤,每个分片都将充当单个 Redis 开源实例。
触发器和函数支持 Redis 集群上的跨分片操作。 这意味着可以调用将在另一个分片上调用的函数。 我们称这种函数为远程函数。
与本地函数一样,必须在使用 redis.registerClusterFunction
API 的库加载时声明远程函数。 以下示例声明了一个远程函数,该函数返回分片上的键数
redis.registerClusterFunction("dbsize", async(async_client) => {
return client.block((async_client) => {
return client.call("dbsize").toString();
});
});
redis.registerClusterFunction
传递远程函数名称,稍后将使用该名称来调用远程函数,以及远程函数代码。 远程函数必须是协程(异步函数),并且在远程分片上的后台执行。 有关异步函数的更多信息,请参阅同步和异步页面。
我们有几种调用远程函数的选项。 这些选项通过提供给协程的异步客户端公开
async_client.runOnShards
- 在所有分片(包括当前分片)上运行远程函数。 返回一个 promise,一旦解决,将给出两个嵌套数组,第一个包含另一个数组,其中包含来自所有分片的结果,另一个包含错误数组 ([[res1, res2, ...],[err1, err2, ..]]
)。async_client.runOnKey
- 在负责给定键的分片上运行远程函数。 返回一个 promise,一旦解决,将给出远程函数执行的结果,或者在出现错误的情况下引发异常。
以下示例注册一个函数,该函数将返回集群上的键总数。 该函数将使用上面定义的远程函数
redis.registerAsyncFunction("my_dbsize", async(async_client) => {
let res = await async_client.runOnShards("dbsize");
let results = res[0];
let errors = res[1];
if (errors.length > 0) {
return errors;
}
let sum = BigInt(0);
results.forEach((element) => sum+=BigInt(element));
return sum;
});
首先,该函数在所有分片上执行一个远程函数,该函数返回每个分片上的键数,然后该函数添加所有结果并返回所有分片的键总数。
这是完整的例子
#!js name=lib api_version=1.0
redis.registerClusterFunction("dbsize", async(client) => {
return client.block((client) => {
return client.call("dbsize").toString();
});
});
redis.registerAsyncFunction("test", async(async_client) => {
let res = await async_client.runOnShards("dbsize");
let results = res[0];
let errors = res[1];
if (errors.length > 0) {
return errors;
}
let sum = BigInt(0);
results.forEach((element) => sum+=BigInt(element));
return sum;
});
参数和结果序列化
可以将参数传递给远程函数。 参数将在 async_client
之后提供给远程函数。 以下示例显示了如何从集群中的任何分片获取键的值
#!js name=lib api_version=1.0
const remote_get = "remote_get";
redis.registerClusterFunction(remote_get, async(client, key) => {
let res = client.block((client) => {
return client.call("get", key);
});
return res;
});
redis.registerAsyncFunction("test", async (async_client) => {
return await async_client.runOnKey("x", remote_get, "x");
});
无论函数在哪个分片上执行,函数 test
都将返回 x
的值。
远程函数参数和结果按以下方式序列化
- 如果参数的类型为
ArrayBuffer
,则数据将按原样发送。 - 否则,RedisGears 将尝试使用
JSON.stringify
将给定的参数(或返回值)序列化为 JSON。 序列化失败将导致引发错误。
执行超时
不允许远程函数永久运行,并且会超时。 可以使用remote-task-default-timeout配置超时时间。 使用 async_client.runOnShards
API 时,超时将作为错误添加到错误数组。 使用 async_client.runOnKey
时,超时将导致引发异常。
远程函数限制
协程上列出的所有限制也适用于远程函数。 远程函数还附带一些额外的限制
- 远程函数只能执行读取操作。 尝试执行写入操作将导致错误。
- 不能保证远程函数会成功(例如,如果分片崩溃)。 在这种情况下,将给出超时错误。