集群支持

触发器和函数的集群支持

注意:在 OSS 集群上,在执行任何齿轮函数之前,你必须向所有分片发送 REDISGEARS_2.REFRESHCLUSTER 命令,以便它们了解集群拓扑。如果没有此步骤,每个分片将充当一个单独的 OSS 实例。

触发器和函数支持对 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 的值,无论函数在哪个分片上执行。

远程函数参数和结果按以下方式序列化

  1. 如果参数的类型为 ArrayBuffer,则数据将按原样发送。
  2. 否则,RedisGears 将尝试使用 JSON.stringify 将给定的参数(或返回值)序列化为 JSON。序列化失败将导致引发错误。

执行超时

远程函数不会被允许无限期运行,并且会超时。超时时间段可以使用 remote-task-default-timeout 进行配置。使用 async_client.runOnShards API 时,超时将作为错误添加到错误数组中。使用 async_client.runOnKey 时,超时会导致引发异常。

远程函数限制

协程 上列出的所有限制也适用于远程函数。远程函数还有一些额外的限制

  • 远程函数只能执行读取操作。尝试执行写入操作会导致错误。
  • 远程函数不能保证成功(例如,如果分片崩溃)。在这种情况下,将给出超时错误。
对本页进行评分