集群支持

触发器和函数的集群支持

注意:在 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 的值,无论函数是在哪个分片上执行的。

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

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

执行超时

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

远程函数限制

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

  • 远程函数只能执行读操作。尝试执行写操作将导致错误。
  • 远程函数不能保证成功(例如,如果分片崩溃)。在这种情况下,将给出超时错误。
RATE THIS PAGE
Back to top ↑