模块 API 参考

Redis 模块 API 参考

部分

堆分配原始函数

Redis key 会考虑使用这些函数分配的内存 驱逐算法,并在 Redis 内存使用信息中报告。

RedisModule_Alloc

void *RedisModule_Alloc(size_t bytes);

从以下版本可用: 4.0.0

使用 likemalloc().使用此函数分配的内存以 Redis INFO 内存,用于根据 maxmemory 设置驱逐键 通常被视为 Redis 分配的内存。 您应该避免使用malloc(). 如果无法分配足够的内存,此函数将出现 panic。

RedisModule_TryAlloc

void *RedisModule_TryAlloc(size_t bytes);

从以下版本可用: 7.0.0

RedisModule_Alloc,但在分配失败的情况下返回 NULL,则返回 NULL 恐慌。

RedisModule_Calloc

void *RedisModule_Calloc(size_t nmemb, size_t size);

从以下版本可用: 4.0.0

使用 likecalloc().使用此函数分配的内存以 Redis INFO 内存,用于根据 maxmemory 设置驱逐键 通常被视为 Redis 分配的内存。 您应该避免使用calloc()径直。

RedisModule_TryCalloc

void *RedisModule_TryCalloc(size_t nmemb, size_t size);

从以下版本可用: 7.4.0

RedisModule_Calloc,但在分配失败的情况下返回 NULL,则返回 NULL 恐慌。

RedisModule_Realloc

void* RedisModule_Realloc(void *ptr, size_t bytes);

从以下版本可用: 4.0.0

使用 likerealloc()对于使用RedisModule_Alloc().

RedisModule_TryRealloc

void *RedisModule_TryRealloc(void *ptr, size_t bytes);

从以下版本可用: 7.4.0

RedisModule_Realloc,但在分配失败的情况下返回 NULL, 而不是惊慌失措。

RedisModule_Free

void RedisModule_Free(void *ptr);

从以下版本可用: 4.0.0

使用 likefree()对于由RedisModule_Alloc()RedisModule_Realloc().但是,您永远不应该尝试使用RedisModule_Free()使用malloc()在你的模块中。

RedisModule_Strdup

char *RedisModule_Strdup(const char *str);

从以下版本可用: 4.0.0

喜欢strdup()但返回使用RedisModule_Alloc().

RedisModule_PoolAlloc

void *RedisModule_PoolAlloc(RedisModuleCtx *ctx, size_t bytes);

从以下版本可用: 4.0.0

返回堆分配的内存,当 module 回调函数返回。最适用于小额分配 生存期较短,必须在回调返回时释放 无论如何。返回的内存与架构字长对齐 如果请求至少字长字节,则只是 与下一个 2 的幂对齐,因此例如 3 字节的请求是 4 字节对齐,而 2 字节请求 2 字节对齐。

没有 realloc 样式函数,因为当需要使用 pool allocator 不是一个好主意。

如果bytes为 0。

命令 API

这些函数用于实现自定义 Redis 命令。

有关示例,请参阅 https://redis.io/topics/modules-intro

RedisModule_IsKeysPositionRequest

int RedisModule_IsKeysPositionRequest(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

如果模块命令是使用 标志 “getkeys-api” 以特殊方式调用以获取键位置 而不是被处决。否则返回 0。

RedisModule_KeyAtPosWithFlags

void RedisModule_KeyAtPosWithFlags(RedisModuleCtx *ctx, int pos, int flags);

从以下版本可用: 7.0.0

当调用模块命令以获取 keys 的 API API 的 API API 的 命令实现使用RedisModule_IsKeysPositionRequest()API 并在 order 来报告 key。

支持的标志是RedisModule_SetCommandInfoREDISMODULE_CMD_KEY_*.

以下是如何使用它的示例:

if (RedisModule_IsKeysPositionRequest(ctx)) {
    RedisModule_KeyAtPosWithFlags(ctx, 2, REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS);
    RedisModule_KeyAtPosWithFlags(ctx, 1, REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE | REDISMODULE_CMD_KEY_ACCESS);
}

注意:在上面的示例中,获取密钥 API 可能已由 key-specs(首选)处理。 仅当无法声明涵盖所有键的 key-spec 时,才需要实现 getkeys-api。

RedisModule_KeyAtPos

void RedisModule_KeyAtPos(RedisModuleCtx *ctx, int pos);

从以下版本可用: 4.0.0

此 API 以前存在RedisModule_KeyAtPosWithFlags已添加,现已弃用,并且 可用于与旧版本兼容,在 key-spec 和 flags 之前 被引入。

RedisModule_IsChannelsPositionRequest

int RedisModule_IsChannelsPositionRequest(RedisModuleCtx *ctx);

从以下版本可用: 7.0.0

如果模块命令是使用 标志 “getChannels-api” 以特殊方式调用以获取频道位置 而不是被处决。否则返回 0。

RedisModule_ChannelAtPosWithFlags

void RedisModule_ChannelAtPosWithFlags(RedisModuleCtx *ctx,
                                       int pos,
                                       int flags);

从以下版本可用: 7.0.0

当调用模块命令以获取 channels 的 API API 中,因为它在 registration,则命令实现会检查此特殊调用 使用RedisModule_IsChannelsPositionRequest()API 并使用此 功能来报告频道。

支持的标志包括:

  • REDISMODULE_CMD_CHANNEL_SUBSCRIBE:此命令将订阅频道。
  • REDISMODULE_CMD_CHANNEL_UNSUBSCRIBE:此命令将取消订阅此频道。
  • REDISMODULE_CMD_CHANNEL_PUBLISH:此命令将发布到此频道。
  • REDISMODULE_CMD_CHANNEL_PATTERN:不是作用于特定通道,而是作用于任何 模式指定的 channel。这是相同的访问权限 由可用的 PSUBSCRIBE 和 PUNSUBSCRIBE 命令使用 在 Redis 中。不适合与 PUBLISH 权限一起使用。

以下是如何使用它的示例:

if (RedisModule_IsChannelsPositionRequest(ctx)) {
    RedisModule_ChannelAtPosWithFlags(ctx, 1, REDISMODULE_CMD_CHANNEL_SUBSCRIBE | REDISMODULE_CMD_CHANNEL_PATTERN);
    RedisModule_ChannelAtPosWithFlags(ctx, 1, REDISMODULE_CMD_CHANNEL_PUBLISH);
}

注意:声明通道的一个用途是评估 ACL 权限。在此上下文中, 始终允许取消订阅,因此将仅针对 subscribe 和 发布权限。这比使用RedisModule_ACLCheckChannelPermissions因为 它允许在执行命令之前检查 ACL。

RedisModule_CreateCommand

int RedisModule_CreateCommand(RedisModuleCtx *ctx,
                              const char *name,
                              RedisModuleCmdFunc cmdfunc,
                              const char *strflags,
                              int firstkey,
                              int lastkey,
                              int keystep);

从以下版本可用: 4.0.0

在 Redis 服务器中注册一个新命令,该命令将由 使用 RedisModule 调用 公约。

该函数返回REDISMODULE_ERR在这些情况下:

  • 如果在RedisModule_OnLoad.
  • 指定的命令已繁忙。
  • 命令名称包含一些不允许使用的字符。
  • 传递了一组无效标志。

否则REDISMODULE_OK,并注册新命令。

此函数必须在模块初始化期间调用 在RedisModule_OnLoad()功能。在外部调用此函数 的初始化函数。

命令函数类型如下:

 int MyCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);

并且应该总是返回REDISMODULE_OK.

标志集 'strflags' 指定命令的行为,并且应该 作为由空格分隔的单词组成的 C 字符串传递,例如 示例“write deny-oom”。标志集包括:

  • “write”:该命令可以修改数据集(它还可能读取 从它)。
  • “readonly”:该命令从 key 返回数据,但从不写入。
  • “admin”:该命令是管理命令(可能会更改 复制或执行类似任务)。
  • “deny-oom”:该命令可能会使用额外的内存,并且应该 在内存不足情况下被拒绝。
  • “deny-script”:不允许在 Lua 脚本中使用此命令。
  • “allow-loading”:在服务器加载数据时允许此命令。 仅与数据集交互的命令 应允许在此模式下运行。如果不确定 请勿使用此标志。
  • “pubsub”:该命令在 Pub/Sub 频道上发布内容。
  • “random”:命令可能具有不同的输出,即使启动 从相同的输入参数和键值。 从 Redis 7.0 开始,此标志已被弃用。 将命令声明为 “random” 可以使用 命令提示,请参见 https://redis.io/topics/command-tips
  • “allow-stale”:允许该命令在不支持 提供过时的数据。如果您不知道什么,请不要使用 这意味着。
  • “no-monitor”:不在 monitor 上传播命令。如果 该命令的参数中包含敏感数据。
  • “no-slowlog”:不要在 slowlog 中记录此命令。如果 该命令的参数中包含敏感数据。
  • “fast”:命令时间复杂度不大 than O(log(N)),其中 N 是集合的大小,或者 表示正常可伸缩性的任何其他内容 问题。
  • “getkeys-api”:该命令实现要返回的接口 作为键的参数。在 start/stop/step 时使用 是不够的,因为命令语法的原因。
  • “no-cluster”:该命令不应在 Redis Cluster 中注册 since 不是为使用它而设计的,因为,对于 example,无法报告 键、以编程方式创建键名称或任何 其他原因。
  • “no-auth”:此命令可由未经身份验证的客户端运行。 通常,这由使用的命令使用 对客户端进行身份验证。
  • “may-replicate”:此命令可能会生成复制流量,甚至 虽然它不是 write 命令。
  • “no-mandatory-keys”:此命令可能采用的所有键都是可选的
  • “blocking”:该命令可能会阻止客户端。
  • “allow-busy”:当服务器被 脚本或通过慢速模块命令,请参阅 RedisModule_Yield。
  • “getchannels-api”:该命令实现要返回的接口 作为 channels 的参数。

最后三个参数指定新命令的参数是 Redis 键。有关更多信息,请参阅 https://redis.io/commands/command

  • firstkey:作为键的第一个参数的从 1 开始的索引。 位置 0 始终是命令名称本身。 0 表示没有键的命令。
  • lastkey:作为键的最后一个参数的从 1 开始的索引。 负数是指从最后一个开始倒数 参数(-1 表示提供的最后一个参数) 0 表示没有键的命令。
  • keystep:在第一个键索引和最后一个键索引之间执行步骤。 0 表示没有键的命令。

此信息由 ACL、Cluster 和COMMAND命令。

注意:上述方案的用途有限,可以 仅用于查找存在于常量索引处的键。 对于重要的 key 参数,你可以传递 0,0,0 并使用RedisModule_SetCommandInfo使用更高级的方案设置关键规范,并使用RedisModule_SetCommandACLCategories设置命令的 Redis ACL 类别。

RedisModule_GetCommand

RedisModuleCommand *RedisModule_GetCommand(RedisModuleCtx *ctx,
                                           const char *name);

从以下版本可用: 7.0.0

按命令名称获取表示模块命令的不透明结构。 此结构用于一些与命令相关的 API。

如果出现以下错误,则返回 NULL:

  • 找不到命令
  • 该命令不是模块命令
  • 该命令不属于调用模块

RedisModule_CreateSubcommand

int RedisModule_CreateSubcommand(RedisModuleCommand *parent,
                                 const char *name,
                                 RedisModuleCmdFunc cmdfunc,
                                 const char *strflags,
                                 int firstkey,
                                 int lastkey,
                                 int keystep);

从以下版本可用: 7.0.0

与 非常相似RedisModule_CreateCommand除了它用于创建 一个子命令,与另一个 container, command 相关联。

示例:如果模块具有配置命令 MODULE.CONFIG,则 GET 和 SET 应该是单独的子命令,而 MODULE.CONFIG 是 命令,但不应使用有效的funcptr:

 if (RedisModule_CreateCommand(ctx,"module.config",NULL,"",0,0,0) == REDISMODULE_ERR)
     return REDISMODULE_ERR;

 RedisModuleCommand *parent = RedisModule_GetCommand(ctx,,"module.config");

 if (RedisModule_CreateSubcommand(parent,"set",cmd_config_set,"",0,0,0) == REDISMODULE_ERR)
    return REDISMODULE_ERR;

 if (RedisModule_CreateSubcommand(parent,"get",cmd_config_get,"",0,0,0) == REDISMODULE_ERR)
    return REDISMODULE_ERR;

返回REDISMODULE_OKon success 和REDISMODULE_ERR如果出现以下错误:

  • 解析时出错strflags
  • Command 标记为no-cluster但启用了群集模式
  • parent已经是一个子命令(我们不允许多个级别的命令嵌套)
  • parent是带有实现 (RedisModuleCmdFunc)(父命令应该是子命令的纯容器)
  • parent已经有一个名为name
  • 创建子命令是在RedisModule_OnLoad.

RedisModule_AddACLCategory

int RedisModule_AddACLCategory(RedisModuleCtx *ctx, const char *name);

从以下版本可用: 7.4.0

RedisModule_AddACLCategory可用于添加新的 ACL 命令类别。类别名称 只能包含字母数字字符、下划线或短划线。只能添加类别 在RedisModule_OnLoad功能。类别一旦添加,就无法删除。 任何模块都可以使用RedisModule_SetCommandACLCategories.

返回:

  • REDISMODULE_OK成功添加新的 ACL 类别。
  • REDISMODULE_ERR失败时。

出错时,errno 设置为:

  • 如果名称包含无效字符,则为 EINVAL。
  • EBUSY(如果类别名称已存在)。
  • ENOMEM 如果类别数量达到 64 个类别的最大限制。

RedisModule_SetCommandACLCategories

int RedisModule_SetCommandACLCategories(RedisModuleCommand *command,
                                        const char *aclflags);

从以下版本可用: 7.2.0

RedisModule_SetCommandACLCategories可用于将 ACL 类别设置为 module 命令和子命令。ACL 类别集应作为 空格分隔的 C 字符串 'aclflags'。

例如,acl 标志 'write slow' 将命令标记为写入的一部分,并且 慢速 ACL 类别。

成功时REDISMODULE_OK返回。出错时REDISMODULE_ERR返回。

此函数只能在RedisModule_OnLoad功能。如果调用 在此函数之外,将返回错误。

RedisModule_SetCommandInfo

int RedisModule_SetCommandInfo(RedisModuleCommand *command,
                               const RedisModuleCommandInfo *info);

从以下版本可用: 7.0.0

设置其他命令信息。

影响COMMAND,COMMAND INFOCOMMAND DOCS簇 ACL 的 API 中,用于过滤之前具有错误参数数的命令 调用到达 Module Code。

此函数可以在使用 创建 命令 后调用RedisModule_CreateCommand并使用RedisModule_GetCommand.信息可以 每个命令只能设置一次,其结构如下:

typedef struct RedisModuleCommandInfo {
    const RedisModuleCommandInfoVersion *version;
    const char *summary;
    const char *complexity;
    const char *since;
    RedisModuleCommandHistoryEntry *history;
    const char *tips;
    int arity;
    RedisModuleCommandKeySpec *key_specs;
    RedisModuleCommandArg *args;
} RedisModuleCommandInfo;

version是可选的。字段说明:

  • version:此字段启用与不同 Redis 版本的兼容性。 始终将此字段设置为REDISMODULE_COMMAND_INFO_VERSION.

  • summary:命令的简短描述(可选)。

  • complexity:复杂性描述(可选)。

  • since:引入命令的版本(可选)。 注意:指定的版本应该是模块的版本,而不是 Redis 版本。

  • history:一个RedisModuleCommandHistoryEntry(可选),即 具有以下字段的结构体:

      const char *since;
      const char *changes;
    

    since是版本字符串,changes是一个描述 变化。数组以零条目终止,即带有 两个字符串都设置为 NULL。

  • tips:关于此命令的一串以空格分隔的提示,用于 客户端和代理。请参阅 https://redis.io/topics/command-tips

  • arity:参数的数量,包括命令名称本身。A 阳性 number 指定参数的确切数量和负数 指定最小参数数,因此使用 -N 表示 >= N. Redis 在将调用传递给模块之前验证调用,因此这可以替换 arity 检查。值为 0(或 省略的 arity 字段)等效于 -2(如果命令具有子命令) 否则为 -1。

  • key_specs:一个RedisModuleCommandKeySpec,以 元素 memset 设置为 0。这是一个试图描述 关键论点的位置比旧的要好RedisModule_CreateCommand参数firstkey,lastkey,keystep如果这三个不是,则需要 足以描述关键位置。检索密钥有两个步骤 positions: 开始搜索 (BS) 索引应该在哪个索引中找到第一个键并找到键 (FK),相对于 BS 的输出,它描述了我们如何 将哪个参数是键。此外,还有一些特定于关键的标志。

    key-spec 导致 RedisModule_CreateCommand重新计算,但提供 这三个参数RedisModule_CreateCommand,以更好地支持旧的 Redis RedisModule_SetCommandInfo不可用的版本。

    请注意,key-specs 并不能完全取代 “getkeys-api” (参见 RedisModule_CreateCommand、RedisModule_IsKeysPositionRequest 和 RedisModule_KeyAtPosWithFlags) 所以 最好同时提供 key-spec 并实现 getkeys-api 的 API 中。

    key-spec 具有以下结构:

      typedef struct RedisModuleCommandKeySpec {
          const char *notes;
          uint64_t flags;
          RedisModuleKeySpecBeginSearchType begin_search_type;
          union {
              struct {
                  int pos;
              } index;
              struct {
                  const char *keyword;
                  int startfrom;
              } keyword;
          } bs;
          RedisModuleKeySpecFindKeysType find_keys_type;
          union {
              struct {
                  int lastkey;
                  int keystep;
                  int limit;
              } range;
              struct {
                  int keynumidx;
                  int firstkey;
                  int keystep;
              } keynum;
          } fk;
      } RedisModuleCommandKeySpec;
    

    RedisModuleCommandKeySpec 的字段说明:

    • notes:关于此关键规范的可选说明或说明。

    • flags:如下所述的 key-spec 标志的按位 or。

    • begin_search_type:这描述了如何发现第一个密钥。 有两种方法可以确定第一个密钥:

      • REDISMODULE_KSPEC_BS_UNKNOWN:无法判断 键 args start 开始。
      • REDISMODULE_KSPEC_BS_INDEX:键参数从常量索引开始。
      • REDISMODULE_KSPEC_BS_KEYWORD:键参数在 specific 关键字。
    • bs:这是一个联合,其中indexkeywordbranch 的 取决于begin_search_type田。

      • bs.index.pos:我们从中开始搜索键的索引。 (REDISMODULE_KSPEC_BS_INDEX仅。

      • bs.keyword.keyword:指示 关键参数的开头。(REDISMODULE_KSPEC_BS_KEYWORD仅。

      • bs.keyword.startfrom:argv 中要开始的索引 搜索。可以是负数,即从末尾开始搜索, 相反。示例:-2 表示从 倒数第二个论点。(REDISMODULE_KSPEC_BS_KEYWORD仅。

    • find_keys_type:在“开始搜索”之后,这描述了哪个 参数是键。这些策略是:

      • REDISMODULE_KSPEC_BS_UNKNOWN:无法判断 key args 的 Alpha 参数。
      • REDISMODULE_KSPEC_FK_RANGE:键以特定索引(或 相对于最后一个参数)。
      • REDISMODULE_KSPEC_FK_KEYNUM:有一个参数包含 键本身之前某个位置的 key args 的数量。

      find_keys_typefk如果此 keyspec 描述了 恰好一个键。

    • fk:这是一个联合,其中rangekeynumbranch 的 取决于find_keys_type田。

      • fk.range(对于REDISMODULE_KSPEC_FK_RANGE):具有 以下字段:

        • lastkey:最后一个键相对于 开始搜索步骤。可以是负数,在这种情况下不是 相对。-1 表示最后一个参数,-2 表示 last 等。

        • keystep:找到 键,以便找到下一个?

        • limit:如果lastkey是 -1,我们使用limit停止搜索 由一个因素。0 和 1 表示没有限制。2 表示 1/2 remaining args,3 表示 1/3,依此类推。

      • fk.keynum(对于REDISMODULE_KSPEC_FK_KEYNUM):具有 以下字段:

        • keynumidx:包含 key to come,相对于 begin search 步骤的结果。

        • firstkey:第一个 key 相对于 开始搜索步骤。(通常是在keynumidx在 应将其设置为keynumidx + 1.)

        • keystep:找到 键,以便找到下一个?

    Key-spec 标志:

    前四个引用命令对值或 键的元数据,不一定是用户数据或其影响 它。每个 key-spec 可能必须恰好包含其中之一。任何作 不是明显的 deletion、overwrite 或 read-only 将被标记为 乌尔曼。

    • REDISMODULE_CMD_KEY_RO:只读。读取 key 的值,但 不一定返回它。

    • REDISMODULE_CMD_KEY_RW:读写。修改存储在 值或其元数据。

    • REDISMODULE_CMD_KEY_OW:改写。覆盖存储在 值。

    • REDISMODULE_CMD_KEY_RM:删除密钥。

    接下来的四个参数是指 key 值内的 user data,而不是 元数据,如 LRU、类型、基数。它指的是逻辑作 在用户的数据(实际输入字符串或 TTL)上,为 used/returned/copied/changed 的。它不是指修改或 返回元数据(如 type、count、presence of data)。ACCESS 可以是 与其中一个写入作 INSERT、DELETE 或 UPDATE 结合使用。任何 write 不是 INSERT 或 DELETE 的 write 将是 UPDATE。

    • REDISMODULE_CMD_KEY_ACCESS:返回、复制或使用用户数据 从 key 的值。

    • REDISMODULE_CMD_KEY_UPDATE:将数据更新为值,新值可能会 依赖于旧值。

    • REDISMODULE_CMD_KEY_INSERT:将数据添加到值中,没有机会 修改或删除现有数据。

    • REDISMODULE_CMD_KEY_DELETE:从 值。

    其他标志:

    • REDISMODULE_CMD_KEY_NOT_KEY:键实际上不是键,而是 应该以集群模式路由,就像它是一个键一样。

    • REDISMODULE_CMD_KEY_INCOMPLETE:keyspec 可能不会指出所有内容 它应该覆盖的键。

    • REDISMODULE_CMD_KEY_VARIABLE_FLAGS:某些键可能具有不同的 标志。

  • args:一个RedisModuleCommandArg,由元素 memset 终止 到 0。RedisModuleCommandArg是一个结构,其中 at 描述的字段 下面。

      typedef struct RedisModuleCommandArg {
          const char *name;
          RedisModuleCommandArgType type;
          int key_spec_index;
          const char *token;
          const char *summary;
          const char *since;
          int flags;
          struct RedisModuleCommandArg *subargs;
      } RedisModuleCommandArg;
    

    字段说明:

    • name:参数的名称。

    • type:参数的类型。有关详细信息,请参阅下文。类型REDISMODULE_ARG_TYPE_ONEOFREDISMODULE_ARG_TYPE_BLOCK需要 具有子参数的参数,即subargs.

    • key_spec_index:如果typeREDISMODULE_ARG_TYPE_KEY您必须 提供与此参数关联的 key-spec 的索引。看key_specs以上。如果参数不是键,则可以指定 -1。

    • token:参数前面的标记(可选)。示例: 论点secondsSET具有令牌EX.如果参数包含 中(例如NXSET),类型应为REDISMODULE_ARG_TYPE_PURE_TOKENvalue应为 NULL。

    • summary:参数的简短描述(可选)。

    • since:包含此参数的第一个版本(可选)。

    • flags:宏的按位 orREDISMODULE_CMD_ARG_*.见下文。

    • value:参数的 display-value。这个字符串应该是 在从COMMAND.如果token不是 NULL,则还应显示它。

    说明RedisModuleCommandArgType:

    • REDISMODULE_ARG_TYPE_STRING: String 参数。
    • REDISMODULE_ARG_TYPE_INTEGER:整数参数。
    • REDISMODULE_ARG_TYPE_DOUBLE:双精度浮点数参数。
    • REDISMODULE_ARG_TYPE_KEY: 表示键名的字符串参数。
    • REDISMODULE_ARG_TYPE_PATTERN:字符串,但正则表达式模式。
    • REDISMODULE_ARG_TYPE_UNIX_TIME:整数,但 Unix 时间戳。
    • REDISMODULE_ARG_TYPE_PURE_TOKEN: 参数没有占位符。 它只是一个没有值的代币。示例:KEEPTTL选项SET命令。
    • REDISMODULE_ARG_TYPE_ONEOF:当用户只能选择以下一项时使用 一些子论点。需要subargs.示例:NXXX选项SET.
    • REDISMODULE_ARG_TYPE_BLOCK:当一个人想要组合在一起时使用 几个子参数,通常用于对所有子参数应用某些内容,例如 将整个组设为 “optional”。需要subargs.示例:LIMIT offset count参数ZRANGE.

    命令参数标志的说明:

    • REDISMODULE_CMD_ARG_OPTIONAL:参数是可选的(如 GET in SET 命令)。
    • REDISMODULE_CMD_ARG_MULTIPLE:参数可以重复自身(如 键)。
    • REDISMODULE_CMD_ARG_MULTIPLE_TOKEN:参数可能会重复, 它的 token 也是如此(如GET pattern在 SORT 中)。

成功时REDISMODULE_OK返回。出错时REDISMODULE_ERR返回 和errno如果提供了无效信息,则设置为 EINVAL,如果提供的信息 已设置。如果信息无效,则会记录一条警告,说明 信息的哪一部分无效以及原因。

模块信息和时间测量

RedisModule_IsModuleNameBusy

int RedisModule_IsModuleNameBusy(const char *name);

从以下版本可用: 4.0.3

如果模块名称繁忙,则返回非零。 否则返回 0。

RedisModule_Milliseconds

mstime_t RedisModule_Milliseconds(void);

从以下版本可用: 4.0.0

返回当前 UNIX 时间(以毫秒为单位)。

RedisModule_MonotonicMicroseconds

uint64_t RedisModule_MonotonicMicroseconds(void);

从以下版本可用: 7.0.0

相对于任意时间点的微秒的返回计数器。

RedisModule_Microseconds

ustime_t RedisModule_Microseconds(void);

从以下版本可用: 7.2.0

返回当前 UNIX 时间(以微秒为单位)

RedisModule_CachedMicroseconds

ustime_t RedisModule_CachedMicroseconds(void);

从以下版本可用: 7.2.0

返回缓存的 UNIX 时间(以微秒为单位)。 它在服务器 cron 作业中和执行命令之前更新。 它对于复杂的调用堆栈非常有用,例如导致 key space 通知,导致模块执行RedisModule_Call, 导致另一个通知,等等。 所有这些回调都将使用相同的 clock 是有道理的。

RedisModule_BlockedClientMeasureTimeStart

int RedisModule_BlockedClientMeasureTimeStart(RedisModuleBlockedClient *bc);

从以下版本可用: 6.2.0

标记一个时间点,作为计算的开始时间 运行时RedisModule_BlockedClientMeasureTimeEnd()被调用。 在同一命令中,您可以多次调用RedisModule_BlockedClientMeasureTimeStart()RedisModule_BlockedClientMeasureTimeEnd()将独立的时间间隔累积到后台持续时间。 此方法始终返回REDISMODULE_OK.

此函数不是线程安全的,如果在模块 thread 中使用并被阻塞回调(可能是主线程) 同时,建议使用 caller 拥有的 lock 而不是 GIL 来保护它们。

RedisModule_BlockedClientMeasureTimeEnd

int RedisModule_BlockedClientMeasureTimeEnd(RedisModuleBlockedClient *bc);

从以下版本可用: 6.2.0

标记将用作结束时间的时间点 以计算已用执行时间。 成功时REDISMODULE_OK返回。 此方法仅返回REDISMODULE_ERR如果没有 Start Time 为 先前定义的 ( 含义RedisModule_BlockedClientMeasureTimeStart未调用 )。

此函数不是线程安全的,如果在模块 thread 中使用并被阻塞回调(可能是主线程) 同时,建议使用 caller 拥有的 lock 而不是 GIL 来保护它们。

RedisModule_Yield

void RedisModule_Yield(RedisModuleCtx *ctx, int flags, const char *busy_reply);

从以下版本可用: 7.0.0

此 API 允许模块让 Redis 处理后台任务,并且一些 命令。 该模块可以定期调用该 API。 flags 是这些的位掩码:

  • REDISMODULE_YIELD_FLAG_NONE:没有特殊标志,可以执行一些背景 作,但不处理客户端命令。
  • REDISMODULE_YIELD_FLAG_CLIENTS:Redis 还可以处理客户端命令。

busy_reply参数是可选的,可用于控制 verbose error 字符串-BUSY错误代码。

REDISMODULE_YIELD_FLAG_CLIENTS,Redis 只会启动 在busy-reply-thresholdconfig,在这种情况下,Redis 将开始拒绝大多数 命令替换为-BUSYerror 的 URL,但允许使用allow-busy标志。 此 API 还可以在线程安全上下文中使用(锁定时),以及在 loading (在rdb_loadcallback,在这种情况下,它将拒绝带有 -LOADING 错误)

RedisModule_SetModuleOptions

void RedisModule_SetModuleOptions(RedisModuleCtx *ctx, int options);

从以下版本可用: 6.0.0

设置定义功能或行为位标志的标志。

REDISMODULE_OPTIONS_HANDLE_IO_ERRORS: 通常,模块不需要为此烦恼,因为该过程只会 terminate,但是,如果发生读取错误,则设置此标志将允许 repl-diskless-load 如果启用,则正常工作。 该模块应使用RedisModule_IsIOError读取后,在使用 读取的数据,如果出现错误,则将其向上传播,并且 能够释放部分填充的值及其所有分配。

REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED: 看RedisModule_SignalModifiedKey().

REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD: 设置此标志表示模块对无盘异步复制的感知 (repl-diskless-load=swapdb) 并且 redis 可以在复制期间提供读取,而不是在 LOADING 状态下阻塞。

REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS: 声明模块想要获取嵌套的键空间通知。 默认情况下,Redis 不会触发 key-space 通知 键空间通知回调。此标志允许更改此行为 并触发嵌套的键空间通知。注意:如果启用,则模块 应该保护自己免受无限递归的影响。

RedisModule_SignalModifiedKey

int RedisModule_SignalModifiedKey(RedisModuleCtx *ctx,
                                  RedisModuleString *keyname);

从以下版本可用: 6.0.0

表示从用户的角度修改了密钥(即使 WATCH 失效 和客户端缓存)。

当打开用于写入的键关闭时,会自动完成此作,除非 选项REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED已使用RedisModule_SetModuleOptions().

模块的自动内存管理

RedisModule_AutoMemory

void RedisModule_AutoMemory(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

启用自动内存管理。

该函数必须作为命令实现的第一个函数调用 ,它想要使用自动内存。

启用后,自动内存管理会跟踪并自动释放 键、调用回复和 Redis 字符串对象。在大多数 这样就无需调用以下函数:

  1. RedisModule_CloseKey()
  2. RedisModule_FreeCallReply()
  3. RedisModule_FreeString()

这些函数在启用自动内存管理后仍可使用。 例如,优化进行大量分配的循环。

字符串对象 API

RedisModule_CreateString

RedisModuleString *RedisModule_CreateString(RedisModuleCtx *ctx,
                                            const char *ptr,
                                            size_t len);

从以下版本可用: 4.0.0

创建新的模块字符串对象。必须释放返回的字符串 跟RedisModule_FreeString(),除非启用了自动内存。

字符串是通过复制len字节数开始 在ptr.不会保留对传递的缓冲区的引用。

模块上下文 'ctx' 是可选的,如果你想创建 上下文范围之外的字符串。但是,在这种情况下,自动的 内存管理将不可用,并且字符串 memory 必须为 手动管理。

RedisModule_CreateStringPrintf

RedisModuleString *RedisModule_CreateStringPrintf(RedisModuleCtx *ctx,
                                                  const char *fmt,
                                                  ...);

从以下版本可用: 4.0.0

从 printf 格式和参数创建新的模块字符串对象。 返回的字符串必须使用RedisModule_FreeString()除非 启用自动内存。

字符串是使用 sds 格式化程序函数创建的sdscatvprintf().

如有必要,传递的上下文 'ctx' 可以为 NULL,请参阅RedisModule_CreateString()文档了解更多信息。

RedisModule_CreateStringFromLongLong

RedisModuleString *RedisModule_CreateStringFromLongLong(RedisModuleCtx *ctx,
                                                        long long ll);

从以下版本可用: 4.0.0

喜欢RedisModule_CreateString(),但会创建一个从long longinteger 而不是获取缓冲区及其长度。

返回的字符串必须使用RedisModule_FreeString()或通过 启用自动内存管理。

如有必要,传递的上下文 'ctx' 可以为 NULL,请参阅RedisModule_CreateString()文档了解更多信息。

RedisModule_CreateStringFromULongLong

RedisModuleString *RedisModule_CreateStringFromULongLong(RedisModuleCtx *ctx,
                                                         unsigned long long ull);

从以下版本可用: 7.0.3

喜欢RedisModule_CreateString(),但会创建一个从unsigned long longinteger 而不是获取缓冲区及其长度。

返回的字符串必须使用RedisModule_FreeString()或通过 启用自动内存管理。

如有必要,传递的上下文 'ctx' 可以为 NULL,请参阅RedisModule_CreateString()文档了解更多信息。

RedisModule_CreateStringFromDouble

RedisModuleString *RedisModule_CreateStringFromDouble(RedisModuleCtx *ctx,
                                                      double d);

从以下版本可用: 6.0.0

喜欢RedisModule_CreateString(),但会创建一个从 double 开始的字符串 而不是获取缓冲区及其长度。

返回的字符串必须使用RedisModule_FreeString()或通过 启用自动内存管理。

RedisModule_CreateStringFromLongDouble

RedisModuleString *RedisModule_CreateStringFromLongDouble(RedisModuleCtx *ctx,
                                                          long double ld,
                                                          int humanfriendly);

从以下版本可用: 6.0.0

喜欢RedisModule_CreateString(),但会创建一个从长 双。

返回的字符串必须使用RedisModule_FreeString()或通过 启用自动内存管理。

如有必要,传递的上下文 'ctx' 可以为 NULL,请参阅RedisModule_CreateString()文档了解更多信息。

RedisModule_CreateStringFromString

RedisModuleString *RedisModule_CreateStringFromString(RedisModuleCtx *ctx,
                                                      const RedisModuleString *str);

从以下版本可用: 4.0.0

喜欢RedisModule_CreateString(),但会创建一个从另一个RedisModuleString.

返回的字符串必须使用RedisModule_FreeString()或通过 启用自动内存管理。

如有必要,传递的上下文 'ctx' 可以为 NULL,请参阅RedisModule_CreateString()文档了解更多信息。

RedisModule_CreateStringFromStreamID

RedisModuleString *RedisModule_CreateStringFromStreamID(RedisModuleCtx *ctx,
                                                        const RedisModuleStreamID *id);

从以下版本可用: 6.2.0

从 Stream ID 创建字符串。返回的字符串必须使用RedisModule_FreeString(),除非启用了自动内存。

传递的上下文ctx如有必要,可以为 NULL。请参阅RedisModule_CreateString()文档了解更多信息。

RedisModule_FreeString

void RedisModule_FreeString(RedisModuleCtx *ctx, RedisModuleString *str);

从以下版本可用: 4.0.0

释放通过 Redis 模块 API 调用之一获取的模块字符串对象 返回 New String 对象。

即使在自动内存管理时也可以调用此函数 已启用。在这种情况下,字符串将尽快释放并删除 从 pool of string 到最后释放。

如果字符串是使用 NULL 上下文 'ctx' 创建的,则还可以 在释放字符串时将 ctx 作为 NULL 传递(但传递上下文不会 创建任何问题)。使用上下文创建的字符串也应释放,同时传递 上下文,因此,如果以后要从上下文中释放字符串,请确保 以使用 NULL 上下文创建它。

此 API 不是线程安全的,访问这些保留字符串(如果它们源自 from a client command arguments)必须在 GIL 锁定的情况下完成。

RedisModule_RetainString

void RedisModule_RetainString(RedisModuleCtx *ctx, RedisModuleString *str);

从以下版本可用: 4.0.0

每次调用此函数,都会使字符串 'str' 需要 对RedisModule_FreeString()为了真正 释放字符串。请注意,自动释放获得的字符串 启用 Modules 自动内存管理计数RedisModule_FreeString()call (它只是自动执行)。

通常,您希望在以下情况下调用此函数: 满足以下条件:

  1. 您已启用自动内存管理。
  2. 您想要创建字符串对象。
  3. 您创建的那些字符串对象需要在回调之后存在 function(例如,命令实现)创建它们会返回。

通常你想要 this 来存储创建的字符串对象 导入到您自己的数据结构中,例如在实现新数据时 类型。

请注意,当内存管理关闭时,您不需要 自创建字符串以来对 RetainString() 的任何调用都将始终导致 转换为位于回调函数返回后的字符串中,如果 不执行 FreeString() 调用。

可以使用 NULL 上下文调用此函数。

当字符串要保留较长时间时,这是很好的 练习也调用RedisModule_TrimStringAllocation()为了 优化内存使用。

引用其他线程中保留字符串的线程化模块必须在保留字符串后立即显式剪裁分配。不做 因此可能会导致 Automatic Triming,这不是线程安全的。

此 API 不是线程安全的,访问这些保留字符串(如果它们源自 from a client command arguments)必须在 GIL 锁定的情况下完成。

RedisModule_HoldString

RedisModuleString* RedisModule_HoldString(RedisModuleCtx *ctx,
                                          RedisModuleString *str);

从以下版本可用: 6.0.7

此功能可以代替RedisModule_RetainString(). 两者的主要区别在于,这个函数将始终 succeed,而RedisModule_RetainString()可能会因为 断言。

该函数返回一个指向RedisModuleString,该 由调用方。它需要调用RedisModule_FreeString()免费 为上下文禁用 Automatic Memory Management 时的字符串。 启用自动内存管理后,您可以调用RedisModule_FreeString()或者让自动化释放它。

此功能比RedisModule_CreateStringFromString()因为只要有可能,它就会避免复制底层的RedisModuleString.使用此功能的缺点是它 可能无法使用RedisModule_StringAppendBuffer()在 返回RedisModuleString.

可以使用 NULL 上下文调用此函数。

当琴弦要长时间保持时,这是好的 练习也调用RedisModule_TrimStringAllocation()为了 优化内存使用。

引用来自其他线程的 held 字符串的线程化模块必须在 string 被持有后立即显式剪裁分配。不做 因此可能会导致 Automatic Triming,这不是线程安全的。

此 API 不是线程安全的,访问这些保留字符串(如果它们源自 from a client command arguments)必须在 GIL 锁定的情况下完成。

RedisModule_StringPtrLen

const char *RedisModule_StringPtrLen(const RedisModuleString *str,
                                     size_t *len);

从以下版本可用: 4.0.0

给定一个字符串模块对象,此函数返回字符串指针 和字符串的长度。返回的指针和 length 应该只 用于只读访问,并且永远不会修改。

RedisModule_StringToLongLong

int RedisModule_StringToLongLong(const RedisModuleString *str, long long *ll);

从以下版本可用: 4.0.0

将字符串转换为long long整数,将其存储在*ll. 返回REDISMODULE_OK成功。如果无法解析字符串 作为 valid、strictlong long(前后无空格)、REDISMODULE_ERR返回。

RedisModule_StringToULongLong

int RedisModule_StringToULongLong(const RedisModuleString *str,
                                  unsigned long long *ull);

从以下版本可用: 7.0.3

将字符串转换为unsigned long long整数,将其存储在*ull. 返回REDISMODULE_OK成功。如果无法解析字符串 作为 valid、strictunsigned long long(前后无空格)、REDISMODULE_ERR返回。

RedisModule_StringToDouble

int RedisModule_StringToDouble(const RedisModuleString *str, double *d);

从以下版本可用: 4.0.0

将字符串转换为 double,并将其存储在*d. 返回REDISMODULE_OK成功时或REDISMODULE_ERR如果字符串为 不是 double 值的有效字符串表示形式。

RedisModule_StringToLongDouble

int RedisModule_StringToLongDouble(const RedisModuleString *str,
                                   long double *ld);

从以下版本可用: 6.0.0

将字符串转换为长 double,并将其存储在*ld. 返回REDISMODULE_OK成功时或REDISMODULE_ERR如果字符串为 不是 double 值的有效字符串表示形式。

RedisModule_StringToStreamID

int RedisModule_StringToStreamID(const RedisModuleString *str,
                                 RedisModuleStreamID *id);

从以下版本可用: 6.2.0

将字符串转换为流 ID,并将其存储在*id. 返回REDISMODULE_OK成功时和返回REDISMODULE_ERR如果字符串 不是流 ID 的有效字符串表示形式。特殊 ID “+” 和 “-” 是允许的。

RedisModule_StringCompare

int RedisModule_StringCompare(const RedisModuleString *a,
                              const RedisModuleString *b);

从以下版本可用: 4.0.0

比较两个字符串对象,如果 a < b, a == b, a > b.字符串将逐字节比较为 2 没有任何编码关注/排序尝试的二进制 blob。

RedisModule_StringAppendBuffer

int RedisModule_StringAppendBuffer(RedisModuleCtx *ctx,
                                   RedisModuleString *str,
                                   const char *buf,
                                   size_t len);

从以下版本可用: 4.0.0

将指定的缓冲区附加到字符串 'str' 中。字符串必须是 由用户创建的字符串,该字符串仅被引用一次,否则REDISMODULE_ERR,且不执行该作。

RedisModule_TrimStringAllocation

void RedisModule_TrimStringAllocation(RedisModuleString *str);

从以下版本可用: 7.0.0

修剪分配给RedisModuleString.

有时RedisModuleString可能为 它比要求多,通常用于构造的 argv 参数 从网络缓冲区。此函数通过重新分配来优化此类字符串 它们的内存,这对于不是短暂的但 保留较长的持续时间。

此作不是线程安全的,只应在 不保证对字符串的并发访问。将其用于 argv string 在字符串可能可用之前 到其他线程通常是安全的。

目前,Redis 还可以在 module 命令返回。但是,明确执行此作仍应为 首选选项:

  1. Redis 的未来版本可能会放弃自动修剪。
  2. 当前实现的自动修剪不是线程安全的。 处理最近保留的字符串的后台线程可能最终会 在与 auto-trim 的争用条件下,这可能会导致 数据损坏。

回复 API

这些函数用于向客户端发送回复。

大多数函数总是返回REDISMODULE_OK所以你可以用它来 'return' 以便从命令实现中返回:

if (... some condition ...)
    return RedisModule_ReplyWithLongLong(ctx,mycount);

使用集合函数进行回复

在启动集合回复后,模块必须调用其他ReplyWith*style 函数来发出集合的元素。 集合类型包括:Array、Map、Set 和 Attribute。

当生成包含许多未知元素的集合时 在此之前,可以使用特殊标志调用REDISMODULE_POSTPONED_LEN (REDISMODULE_POSTPONED_ARRAY_LEN过去), 实际的元素数量可以在以后使用RedisModule_ReplySet*长度() call (如果有多个 ),它将设置最新的 “open” 计数)。

RedisModule_WrongArity

int RedisModule_WrongArity(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

发送有关给定命令的参数数量的错误, 在错误消息中引用命令名称。返回REDISMODULE_OK.

例:

if (argc != 3) return RedisModule_WrongArity(ctx);

RedisModule_ReplyWithLongLong

int RedisModule_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll);

从以下版本可用: 4.0.0

向客户端发送一个整数回复,其中包含指定的long long价值。 该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithError

int RedisModule_ReplyWithError(RedisModuleCtx *ctx, const char *err);

从以下版本可用: 4.0.0

回复错误 'err'。

请注意,'err' 必须包含所有错误,包括 初始错误代码。该函数仅提供初始 “-”,因此 例如,用法为:

RedisModule_ReplyWithError(ctx,"ERR Wrong Type");

而不仅仅是:

RedisModule_ReplyWithError(ctx,"Wrong Type");

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithErrorFormat

int RedisModule_ReplyWithErrorFormat(RedisModuleCtx *ctx,
                                     const char *fmt,
                                     ...);

从以下版本可用: 7.2.0

回复错误 create from a printf format and arguments。

请注意,'fmt' 必须包含所有错误,包括 初始错误代码。该函数仅提供初始 “-”,因此 例如,用法为:

RedisModule_ReplyWithErrorFormat(ctx,"ERR Wrong Type: %s",type);

而不仅仅是:

RedisModule_ReplyWithErrorFormat(ctx,"Wrong Type: %s",type);

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithSimpleString

int RedisModule_ReplyWithSimpleString(RedisModuleCtx *ctx, const char *msg);

从以下版本可用: 4.0.0

使用简单字符串 (+... \r\n在 RESP 协议中)。这回复 仅适用于发送具有 small overhead 中,例如 “OK” 或类似回复。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithArray

int RedisModule_ReplyWithArray(RedisModuleCtx *ctx, long len);

从以下版本可用: 4.0.0

回复数组类型的 'len' 元素。

在启动数组回复后,模块必须使len对其他ReplyWith*style 函数来发出数组的元素。 有关更多详细信息,请参阅回复 API 部分。

RedisModule_ReplySetArrayLength()以设置延迟长度。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithMap

int RedisModule_ReplyWithMap(RedisModuleCtx *ctx, long len);

从以下版本可用: 7.0.0

回复 RESP3 Map 类型的 'len' 对。 请访问 https://github.com/antirez/RESP3/blob/master/spec.md 了解有关 RESP3 的更多信息。

启动 map 回复后,模块必须进行len*2对其他ReplyWith*style 函数来发出 Map 的元素。 有关更多详细信息,请参阅回复 API 部分。

如果连接的客户端正在使用 RESP2,则回复将转换为平面 数组。

RedisModule_ReplySetMapLength()以设置延迟长度。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithSet

int RedisModule_ReplyWithSet(RedisModuleCtx *ctx, long len);

从以下版本可用: 7.0.0

回复 RESP3 Set 类型的 'len' 元素。 请访问 https://github.com/antirez/RESP3/blob/master/spec.md 了解有关 RESP3 的更多信息。

开始 set 回复后,模块必须进行len对其他ReplyWith*style 函数来发出 set 的元素。 有关更多详细信息,请参阅回复 API 部分。

如果连接的客户端正在使用 RESP2,则回复将转换为 数组类型。

RedisModule_ReplySetSetLength()以设置延迟长度。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithAttribute

int RedisModule_ReplyWithAttribute(RedisModuleCtx *ctx, long len);

从以下版本可用: 7.0.0

将属性 (元数据) 添加到回复中。应该在添加 实际回复。请参阅 https://github.com/antirez/RESP3/blob/master/spec.md #attribute 型

在开始一个 attribute 的回复后,模块必须使len*2对其他ReplyWith*style 函数来发出 attribute map 的元素。 有关更多详细信息,请参阅回复 API 部分。

RedisModule_ReplySetAttributeLength()以设置延迟长度。

RESP2 不支持,将返回REDISMODULE_ERR否则 该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithNullArray

int RedisModule_ReplyWithNullArray(RedisModuleCtx *ctx);

从以下版本可用: 6.0.0

用 null 数组回复客户端,在 RESP3 中只需 null, null 数组。

注意:在 RESP3 中,Null reply 和 NullArray 回复,因此为了防止歧义,最好避免 使用此 API 并使用RedisModule_ReplyWithNull相反。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithEmptyArray

int RedisModule_ReplyWithEmptyArray(RedisModuleCtx *ctx);

从以下版本可用: 6.0.0

使用空数组回复客户端。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplySetArrayLength

void RedisModule_ReplySetArrayLength(RedisModuleCtx *ctx, long len);

从以下版本可用: 4.0.0

什么时候RedisModule_ReplyWithArray()与参数REDISMODULE_POSTPONED_LEN,因为我们事先不知道数字 我们要作为数组的元素输出的项目,这个函数 将注意设置数组长度。

由于可能有多个数组回复待处理,并且未知 length 时,该函数保证始终设置最新的数组长度 这是以一种延迟的方式创建的。

例如,为了输出像 [1,[10,20,30]] 这样的数组,我们 可以写入:

 RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
 RedisModule_ReplyWithLongLong(ctx,1);
 RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
 RedisModule_ReplyWithLongLong(ctx,10);
 RedisModule_ReplyWithLongLong(ctx,20);
 RedisModule_ReplyWithLongLong(ctx,30);
 RedisModule_ReplySetArrayLength(ctx,3); // Set len of 10,20,30 array.
 RedisModule_ReplySetArrayLength(ctx,2); // Set len of top array

请注意,在上面的示例中,没有理由推迟数组 length,因为我们生成了固定数量的元素,但在实践中 代码可以使用迭代器或其他方式创建输出,因此 提前计算元素的数量并不容易。

RedisModule_ReplySetMapLength

void RedisModule_ReplySetMapLength(RedisModuleCtx *ctx, long len);

从以下版本可用: 7.0.0

与 非常相似RedisModule_ReplySetArrayLength除了len应该 正好是ReplyWith*在 map 的上下文。 请访问 https://github.com/antirez/RESP3/blob/master/spec.md 了解有关 RESP3 的更多信息。

RedisModule_ReplySetSetLength

void RedisModule_ReplySetSetLength(RedisModuleCtx *ctx, long len);

从以下版本可用: 7.0.0

与 非常相似RedisModule_ReplySetArrayLength请访问 https://github.com/antirez/RESP3/blob/master/spec.md 了解有关 RESP3 的更多信息。

RedisModule_ReplySetAttributeLength

void RedisModule_ReplySetAttributeLength(RedisModuleCtx *ctx, long len);

从以下版本可用: 7.0.0

与 非常相似RedisModule_ReplySetMapLength请访问 https://github.com/antirez/RESP3/blob/master/spec.md 了解有关 RESP3 的更多信息。

如果RedisModule_ReplyWithAttribute返回错误。

RedisModule_ReplyWithStringBuffer

int RedisModule_ReplyWithStringBuffer(RedisModuleCtx *ctx,
                                      const char *buf,
                                      size_t len);

从以下版本可用: 4.0.0

使用批量字符串回复,输入一个 C 缓冲区指针和长度。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithCString

int RedisModule_ReplyWithCString(RedisModuleCtx *ctx, const char *buf);

从以下版本可用: 5.0.6

使用批量字符串进行回复,输入一个 C 缓冲区指针,该指针是 假定以 null 结尾。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithString

int RedisModule_ReplyWithString(RedisModuleCtx *ctx, RedisModuleString *str);

从以下版本可用: 4.0.0

使用批量字符串回复,并接收输入RedisModuleString对象。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithEmptyString

int RedisModule_ReplyWithEmptyString(RedisModuleCtx *ctx);

从以下版本可用: 6.0.0

使用空字符串进行回复。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithVerbatimStringType

int RedisModule_ReplyWithVerbatimStringType(RedisModuleCtx *ctx,
                                            const char *buf,
                                            size_t len,
                                            const char *ext);

从以下版本可用: 7.0.0

使用二进制安全字符串进行回复,该字符串不应被转义或过滤 输入一个 C 缓冲区指针、长度和一个 3 个字符的类型/扩展名。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithVerbatimString

int RedisModule_ReplyWithVerbatimString(RedisModuleCtx *ctx,
                                        const char *buf,
                                        size_t len);

从以下版本可用: 6.0.0

使用二进制安全字符串进行回复,该字符串不应被转义或过滤 接收 input a C buffer pointer和length。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithNull

int RedisModule_ReplyWithNull(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

使用 NULL 回复客户端。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithBool

int RedisModule_ReplyWithBool(RedisModuleCtx *ctx, int b);

从以下版本可用: 7.0.0

使用 RESP3 布尔类型进行回复。 请访问 https://github.com/antirez/RESP3/blob/master/spec.md 了解有关 RESP3 的更多信息。

在 RESP3 中,这是布尔类型 在 RESP2 中,true 和 false 分别是 “1” 和 “0” 的字符串响应。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithCallReply

int RedisModule_ReplyWithCallReply(RedisModuleCtx *ctx,
                                   RedisModuleCallReply *reply);

从以下版本可用: 4.0.0

准确回复 Redis 命令返回给我们的内容RedisModule_Call(). 当我们使用RedisModule_Call()为了 执行一些命令,因为我们想要准确地回复客户端 我们从指挥部得到的答复是一样的。

返回:

  • REDISMODULE_OK成功。
  • REDISMODULE_ERR如果给定的回复是 RESP3 格式,但客户端需要 RESP2。 如果出现错误,则 module 编写者负责翻译回复 添加到 RESP2 中(或通过返回错误以不同的方式处理它)。请注意,对于 module writer 方便,可以传递0作为 fmt 的参数 的参数RedisModule_Call这样,RedisModuleCallReply将返回相同的 协议(RESP2 或 RESP3)。

RedisModule_ReplyWithDouble

int RedisModule_ReplyWithDouble(RedisModuleCtx *ctx, double d);

从以下版本可用: 4.0.0

回复 RESP3 Double 类型。 请访问 https://github.com/antirez/RESP3/blob/master/spec.md 了解有关 RESP3 的更多信息。

发送将双倍 'd' 转换为批量字符串的字符串回复。 这个函数基本上等同于将一个 double 转换为 将字符串放入 C 缓冲区中,然后调用函数RedisModule_ReplyWithStringBuffer()替换为 buffer 和 length。

在 RESP3 中,字符串被标记为 double,而在 RESP2 中,它只是一个普通字符串 用户将不得不解析。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithBigNumber

int RedisModule_ReplyWithBigNumber(RedisModuleCtx *ctx,
                                   const char *bignum,
                                   size_t len);

从以下版本可用: 7.0.0

使用 RESP3 BigNumber 类型进行回复。 请访问 https://github.com/antirez/RESP3/blob/master/spec.md 了解有关 RESP3 的更多信息。

在 RESP3 中,这是一个长度为len被标记为 BigNumber, 但是,由调用方来确保它是有效的 BigNumber。 在 RESP2 中,这只是一个普通的批量字符串响应。

该函数始终返回REDISMODULE_OK.

RedisModule_ReplyWithLongDouble

int RedisModule_ReplyWithLongDouble(RedisModuleCtx *ctx, long double ld);

从以下版本可用: 6.0.0

发送将长双双 'ld' 转换为批量的字符串回复 字符串。这个函数基本上等同于转换一个 long double 放入字符串中,然后调用函数RedisModule_ReplyWithStringBuffer()替换为 buffer 和 length。 double 字符串使用人类可读的格式(请参阅addReplyHumanLongDouble在 networking.c 中)。

该函数始终返回REDISMODULE_OK.

命令复制 API

RedisModule_Replicate

int RedisModule_Replicate(RedisModuleCtx *ctx,
                          const char *cmdname,
                          const char *fmt,
                          ...);

从以下版本可用: 4.0.0

将指定的命令和参数复制到 slaves 和 AOF,作为效果 执行调用命令实现。

复制的命令始终包装在 MULTI/EXEC 中,该 包含在给定模块 command 中复制的所有命令 执行,按照执行的顺序执行。

模块应尝试使用一个接口或另一个接口。

此命令遵循与RedisModule_Call(), 因此,必须传递一组格式说明符,后跟参数 匹配提供的格式说明符。

请参考RedisModule_Call()了解更多信息。

使用特殊的 “A” 和 “R” 修饰符,调用方可以排除 AOF 或来自指定命令传播的副本。 否则,默认情况下,命令将在两个通道中传播。

关于从线程安全上下文调用此函数的注意事项:

通常,当您从实现 module 命令,或者 Redis Module API 提供的任何其他回调, Redis 将在 回调,并将传播包装在 MULTI/EXEC 中的所有命令 交易。但是,当从线程安全上下文调用此函数时 可以存在不确定的时间,并且可以在 需要注意的是,这个 API 不是线程安全的,并且 必须在持有 GIL 时执行。

返回值

该命令返回REDISMODULE_ERR如果格式说明符无效 或者命令名称不属于已知命令。

RedisModule_ReplicateVerbatim

int RedisModule_ReplicateVerbatim(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

此函数将完全按照调用命令的方式复制命令 由客户。请注意,复制的命令始终被包装 放入 MULTI/EXEC 中,其中包含在 given module 命令执行,按照它们的执行顺序执行。

基本上,这种形式的复制在您想要传播时很有用 命令与 slaves 和 AOF 文件完全相同,因为 只需重新执行该命令即可确定性地重新创建 new state 从 old state 开始。

需要注意的是,此 API 不是线程安全的,并且 必须在持有 GIL 时执行。

该函数始终返回REDISMODULE_OK.

数据库和关键 API – 通用 API

RedisModule_GetClientId

unsigned long long RedisModule_GetClientId(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

返回调用当前活动模块的当前客户端的 ID 命令。返回的 ID 有一些保证:

  1. 每个不同客户端的 ID 都不同,因此如果同一客户端 多次执行一个 module 命令,可以识别为 具有相同的 ID,否则 ID 将不同。
  2. ID 单调增加。稍后连接到服务器的客户端 保证获得的 ID 大于以前看到的任何过去 ID。

有效 ID 为 1 到 2^64 - 1。如果返回 0,则表示没有办法 在当前调用函数的上下文中获取 ID。

获取 ID 后,可以检查命令是否执行 实际上发生在 AOF 加载的上下文中,使用以下宏:

 if (RedisModule_IsAOFClient(RedisModule_GetClientId(ctx)) {
     // Handle it differently.
 }

RedisModule_GetClientUserNameById

RedisModuleString *RedisModule_GetClientUserNameById(RedisModuleCtx *ctx,
                                                     uint64_t id);

从以下版本可用: 6.2.1

返回具有指定客户端 ID 的客户端使用的 ACL 用户名。 客户端 ID 可以通过RedisModule_GetClientId()应用程序接口。如果客户端没有 exist,则返回 NULL 并将 errno 设置为 ENOENT。如果客户端不是 使用 ACL 用户时,返回 NULL 并将 errno 设置为 ENOTSUP

RedisModule_GetClientInfoById

int RedisModule_GetClientInfoById(void *ci, uint64_t id);

从以下版本可用: 6.0.0

返回有关具有指定 ID 的客户端的信息(即 之前通过RedisModule_GetClientId()API) 的 API 进行。如果 client 存在,REDISMODULE_OK返回,否则REDISMODULE_ERR返回。

当客户端存在且cipointer 不是 NULL,但指向 类型RedisModuleClientInfoV1 中,之前使用 正确的REDISMODULE_CLIENTINFO_INITIALIZER_V1,则结构将被填充 具有以下字段:

 uint64_t flags;         // REDISMODULE_CLIENTINFO_FLAG_*
 uint64_t id;            // Client ID
 char addr[46];          // IPv4 or IPv6 address.
 uint16_t port;          // TCP port.
 uint16_t db;            // Selected DB.

注意:客户端 ID 在这个调用的上下文中是无用的,因为我们 已经知道,但是相同的结构可以用于其他 我们不知道客户端 ID,但结构相同的上下文 返回。

标志具有以下含义:

REDISMODULE_CLIENTINFO_FLAG_SSL          Client using SSL connection.
REDISMODULE_CLIENTINFO_FLAG_PUBSUB       Client in Pub/Sub mode.
REDISMODULE_CLIENTINFO_FLAG_BLOCKED      Client blocked in command.
REDISMODULE_CLIENTINFO_FLAG_TRACKING     Client with keys tracking on.
REDISMODULE_CLIENTINFO_FLAG_UNIXSOCKET   Client using unix domain socket.
REDISMODULE_CLIENTINFO_FLAG_MULTI        Client in MULTI state.

但是,传递 NULL 是一种检查 Client 端是否存在 我们对任何其他信息不感兴趣。

当我们需要 client info 结构时,这是正确的用法 返回:

 RedisModuleClientInfo ci = REDISMODULE_CLIENTINFO_INITIALIZER;
 int retval = RedisModule_GetClientInfoById(&ci,client_id);
 if (retval == REDISMODULE_OK) {
     printf("Address: %s\n", ci.addr);
 }

RedisModule_GetClientNameById

RedisModuleString *RedisModule_GetClientNameById(RedisModuleCtx *ctx,
                                                 uint64_t id);

从以下版本可用: 7.0.3

返回具有给定 ID 的客户端连接的名称。

如果客户端 ID 不存在,或者客户端没有与 it,则返回 NULL。

RedisModule_SetClientNameById

int RedisModule_SetClientNameById(uint64_t id, RedisModuleString *name);

从以下版本可用: 7.0.3

设置具有给定 ID 的客户端的名称。这相当于客户端调用CLIENT SETNAME name.

返回REDISMODULE_OK成功。失败时,REDISMODULE_ERR返回 和 errno 的设置如下:

  • ENOENT(如果客户端不存在)
  • 如果名称包含无效字符,则为 EINVAL

RedisModule_PublishMessage

int RedisModule_PublishMessage(RedisModuleCtx *ctx,
                               RedisModuleString *channel,
                               RedisModuleString *message);

从以下版本可用: 6.0.0

向订阅者发布消息(请参阅 PUBLISH 命令)。

RedisModule_PublishMessageShard

int RedisModule_PublishMessageShard(RedisModuleCtx *ctx,
                                    RedisModuleString *channel,
                                    RedisModuleString *message);

从以下版本可用: 7.0.0

向分片订阅者发布消息(请参阅 SPUBLISH 命令)。

RedisModule_GetSelectedDb

int RedisModule_GetSelectedDb(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

返回当前选定的 DB。

RedisModule_GetContextFlags

int RedisModule_GetContextFlags(RedisModuleCtx *ctx);

从以下版本可用: 4.0.3

返回当前上下文的标志。这些标志提供有关 当前请求上下文(无论客户端是 Lua 脚本还是 MULTI 中), 以及一般的 Redis 实例,即复制和持久性。

但是,即使使用 NULL 上下文也可以调用此函数 在这种情况下,不会报告以下标志:

  • LUA、MULTI、REPLICATED、DIRTY(有关更多信息,请参见下文)。

可用标志及其含义:

  • REDISMODULE_CTX_FLAGS_LUA:命令在 Lua 脚本中运行

  • REDISMODULE_CTX_FLAGS_MULTI:命令在事务内运行

  • REDISMODULE_CTX_FLAGS_REPLICATED:命令是通过复制发送的 由 MASTER 链接

  • REDISMODULE_CTX_FLAGS_MASTER:Redis 实例是 master 实例

  • REDISMODULE_CTX_FLAGS_SLAVE:Redis 实例是从实例

  • REDISMODULE_CTX_FLAGS_READONLY:Redis 实例为只读实例

  • REDISMODULE_CTX_FLAGS_CLUSTER:Redis 实例处于集群模式

  • REDISMODULE_CTX_FLAGS_AOF:Redis 实例已启用 AOF

  • REDISMODULE_CTX_FLAGS_RDB:实例已启用 RDB

  • REDISMODULE_CTX_FLAGS_MAXMEMORY:实例设置了 Maxmemory

  • REDISMODULE_CTX_FLAGS_EVICT:Maxmemory 已设置并具有驱逐 可能会删除键的策略

  • REDISMODULE_CTX_FLAGS_OOM:Redis 内存不足,根据 maxmemory 设置。

  • REDISMODULE_CTX_FLAGS_OOM_WARNING:之前剩余的内存少于 25% 达到 maxMemory 级别。

  • REDISMODULE_CTX_FLAGS_LOADING:服务器正在加载 RDB/AOF

  • REDISMODULE_CTX_FLAGS_REPLICA_IS_STALE:与 master 没有活动链接。

  • REDISMODULE_CTX_FLAGS_REPLICA_IS_CONNECTING:副本正在尝试 与主服务器连接。

  • REDISMODULE_CTX_FLAGS_REPLICA_IS_TRANSFERRING:主 -> 副本 RDB 转移正在进行中。

  • REDISMODULE_CTX_FLAGS_REPLICA_IS_ONLINE:副本具有活动链接 和它的主人。这是 与 STALE 状态相反。

  • REDISMODULE_CTX_FLAGS_ACTIVE_CHILD: 目前有一些背景 进程活动(RDB、AUX 或模块)。

  • REDISMODULE_CTX_FLAGS_MULTI_DIRTY:下一个 EXEC 将因脏 CAS (触摸键)。

  • REDISMODULE_CTX_FLAGS_IS_CHILD:Redis 当前在 后台子进程。

  • REDISMODULE_CTX_FLAGS_RESP3:表示附加到此的客户端 context 正在使用 RESP3。

  • REDISMODULE_CTX_FLAGS_SERVER_STARTUP:Redis 实例正在启动

RedisModule_AvoidReplicaTraffic

int RedisModule_AvoidReplicaTraffic(void);

从以下版本可用: 6.0.0

如果客户端向服务器发送 CLIENT PAUSE 命令,则返回 true,或者 如果 Redis Cluster 执行手动故障转移,则暂停客户端。 当我们有一个带有副本的 master 并且想要写入 在不向复制通道添加更多数据的情况下,副本 replication offset 的 Offset 中,匹配 master 的 1 个。当这种情况发生时,它是 可以安全地故障转移主服务器而不会丢失数据。

但是,模块可以通过调用RedisModule_Call()跟 “!” 标志,或者通过调用RedisModule_Replicate(),在外部的上下文中 命令执行,例如在超时回调中,线程安全 上下文,依此类推。当 modules 会产生过多的流量时,它会 将很难匹配 master 和 replicas 偏移量,因为存在 是在复制通道中发送的更多数据。

因此,模块可能希望尽量避免非常繁重的后台工作,这些工作具有 创建数据到复制通道的效果,当这个函数 返回 true。这对于具有 background 的模块最有用 垃圾回收任务,或者执行写入和复制此类写入的任务 定期在定时器回调或其他周期性回调中。

RedisModule_SelectDb

int RedisModule_SelectDb(RedisModuleCtx *ctx, int newid);

从以下版本可用: 4.0.0

更改当前选定的 DB。如果 id 超出范围。

请注意,即使在 调用此函数的模块实现的 Redis 命令 返回。

如果 module 命令希望更改其他 DB 中的某些内容,并且 返回到原始 URL,它应该调用RedisModule_GetSelectedDb()before 的 DB 编号,以便在返回之前恢复旧的数据库编号。

RedisModule_KeyExists

int RedisModule_KeyExists(RedisModuleCtx *ctx, robj *keyname);

从以下版本可用: 7.0.0

检查 key 是否存在,不影响其上次访问时间。

这相当于调用RedisModule_OpenKey与模式REDISMODULE_READ|REDISMODULE_OPEN_KEY_NOTOUCH,然后检查是否返回 NULL,如果没有,则检查 叫RedisModule_CloseKey在打开的键上。

RedisModule_OpenKey

RedisModuleKey *RedisModule_OpenKey(RedisModuleCtx *ctx,
                                    robj *keyname,
                                    int mode);

从以下版本可用: 4.0.0

返回一个表示 Redis 键的句柄,以便可以 以 key handle 作为参数调用其他 API 以执行 作。

返回值是表示键的句柄,该句柄必须为 结束方式RedisModule_CloseKey().

如果 key 不存在且REDISMODULE_WRITEmode 时,句柄 仍然返回,因为可以在 一个尚不存在的键(例如,将在 list push作)。如果模式只是REDISMODULE_READ相反,而 key 不存在,则返回 NULL。但是,它仍然是安全的 叫RedisModule_CloseKey()RedisModule_KeyType()在 NULL 上 价值。

可以在 mode 参数下传递给 API 的额外标志:

  • REDISMODULE_OPEN_KEY_NOTOUCH- 打开时避免触摸钥匙的 LRU/LFU。
  • REDISMODULE_OPEN_KEY_NONOTIFY- 不要在键未命中时触发 keyspace 事件。
  • REDISMODULE_OPEN_KEY_NOSTATS- 不要更新 keyspace 命中/未命中计数器。
  • REDISMODULE_OPEN_KEY_NOEXPIRE- 避免删除延迟过期的密钥。
  • REDISMODULE_OPEN_KEY_NOEFFECTS- 避免获取密钥产生任何影响。

RedisModule_GetOpenKeyModesAll

int RedisModule_GetOpenKeyModesAll(void);

从以下版本可用: 7.2.0

使用返回值返回完整的 OpenKey 模式掩码 该模块可以检查是否支持某组 OpenKey 模式 按正在使用的 Redis 服务器版本。 例:

   int supportedMode = RedisModule_GetOpenKeyModesAll();
   if (supportedMode & REDISMODULE_OPEN_KEY_NOTOUCH) {
         // REDISMODULE_OPEN_KEY_NOTOUCH is supported
   } else{
         // REDISMODULE_OPEN_KEY_NOTOUCH is not supported
   }

RedisModule_CloseKey

void RedisModule_CloseKey(RedisModuleKey *key);

从以下版本可用: 4.0.0

关闭键控点。

RedisModule_KeyType

int RedisModule_KeyType(RedisModuleKey *key);

从以下版本可用: 4.0.0

返回键的类型。如果键指针为 NULL,则REDISMODULE_KEYTYPE_EMPTY返回。

RedisModule_ValueLength

size_t RedisModule_ValueLength(RedisModuleKey *key);

从以下版本可用: 4.0.0

返回与键关联的值的长度。 对于字符串,这是字符串的长度。对于所有其他类型的 是元素的数量(仅计算哈希的键)。

如果 key 指针为 NULL 或 key 为空,则返回 0。

RedisModule_DeleteKey

int RedisModule_DeleteKey(RedisModuleKey *key);

从以下版本可用: 4.0.0

如果密钥已打开以供写入,请将其删除,并将密钥设置为 接受新写入作为空键(将按需创建)。 成功时REDISMODULE_OK返回。如果 的密钥未打开 写作REDISMODULE_ERR返回。

RedisModule_UnlinkKey

int RedisModule_UnlinkKey(RedisModuleKey *key);

从以下版本可用: 4.0.7

如果密钥已打开以供写入,请取消链接它(即在 非阻塞方式,而不是立即回收内存),并将 key 设置为 接受新写入作为空键(将按需创建)。 成功时REDISMODULE_OK返回。如果 的密钥未打开 写作REDISMODULE_ERR返回。

RedisModule_GetExpire

mstime_t RedisModule_GetExpire(RedisModuleKey *key);

从以下版本可用: 4.0.0

返回密钥 expire 值,以剩余 TTL 的毫秒数表示。 如果没有 TTL 与该 key 关联或该 key 为空,REDISMODULE_NO_EXPIRE返回。

RedisModule_SetExpire

int RedisModule_SetExpire(RedisModuleKey *key, mstime_t expire);

从以下版本可用: 4.0.0

为密钥设置新的过期时间。如果 Special 过期REDISMODULE_NO_EXPIRE设置了 Expire 时,如果存在 one(与 PERSIST 命令相同)。

请注意,expire 必须以正整数的形式提供,表示 密钥应具有的 TTL 毫秒数。

该函数返回REDISMODULE_OK成功时或REDISMODULE_ERR如果 密钥未打开写入或为空密钥。

RedisModule_GetAbsExpire

mstime_t RedisModule_GetAbsExpire(RedisModuleKey *key);

从以下版本可用: 6.2.2

返回密钥 expire 值,作为绝对 Unix 时间戳。 如果没有 TTL 与该 key 关联或该 key 为空,REDISMODULE_NO_EXPIRE返回。

RedisModule_SetAbsExpire

int RedisModule_SetAbsExpire(RedisModuleKey *key, mstime_t expire);

从以下版本可用: 6.2.2

为密钥设置新的过期时间。如果 Special 过期REDISMODULE_NO_EXPIRE设置了 Expire 时,如果存在 one(与 PERSIST 命令相同)。

请注意,expire 必须以正整数的形式提供,表示 密钥应具有的绝对 Unix 时间戳。

该函数返回REDISMODULE_OK成功时或REDISMODULE_ERR如果 密钥未打开写入或为空密钥。

RedisModule_ResetDataset

void RedisModule_ResetDataset(int restart_aof, int async);

从以下版本可用: 6.0.0

执行与 FLUSHALL 类似的作,并选择性地启动新的 AOF 文件(如果启用) 如果restart_aof为 true,则必须确保触发此调用的命令不是 传播到 AOF 文件。 当 async 设置为 true 时,db 内容将由后台线程释放。

RedisModule_DbSize

unsigned long long RedisModule_DbSize(RedisModuleCtx *ctx);

从以下版本可用: 6.0.0

返回当前数据库中的 key 数。

RedisModule_RandomKey

RedisModuleString *RedisModule_RandomKey(RedisModuleCtx *ctx);

从以下版本可用: 6.0.0

返回随机键的名称,如果当前 db 为空,则返回 NULL。

RedisModule_GetKeyNameFromOptCtx

const RedisModuleString *RedisModule_GetKeyNameFromOptCtx(RedisModuleKeyOptCtx *ctx);

从以下版本可用: 7.0.0

返回当前正在处理的键的名称。

RedisModule_GetToKeyNameFromOptCtx

const RedisModuleString *RedisModule_GetToKeyNameFromOptCtx(RedisModuleKeyOptCtx *ctx);

从以下版本可用: 7.0.0

返回当前正在处理的目标键的名称。

RedisModule_GetDbIdFromOptCtx

int RedisModule_GetDbIdFromOptCtx(RedisModuleKeyOptCtx *ctx);

从以下版本可用: 7.0.0

返回当前正在处理的 dbid。

RedisModule_GetToDbIdFromOptCtx

int RedisModule_GetToDbIdFromOptCtx(RedisModuleKeyOptCtx *ctx);

从以下版本可用: 7.0.0

返回当前正在处理的目标 dbid。

String 类型的关键 API

另请参阅RedisModule_ValueLength(),它返回字符串的长度。

RedisModule_StringSet

int RedisModule_StringSet(RedisModuleKey *key, RedisModuleString *str);

从以下版本可用: 4.0.0

如果 key 是开放写入的,则将指定的字符串 'str' 设置为 值,删除旧值(如果有)。 成功时REDISMODULE_OK返回。如果 的密钥未打开 写入或有一个活动的迭代器,REDISMODULE_ERR返回。

RedisModule_StringDMA

char *RedisModule_StringDMA(RedisModuleKey *key, size_t *len, int mode);

从以下版本可用: 4.0.0

为 DMA 访问准备与密钥关联的字符串值,并返回 用户可用于读取或 就地修改字符串,通过 Pointer 直接访问它。

'mode' 由按位 OR 对以下标志进行 OR 运算组成:

REDISMODULE_READ -- Read access
REDISMODULE_WRITE -- Write access

如果未请求写入 DMA,则返回的指针应 只能以只读方式访问。

出错时 (错误类型) 返回 NULL。

DMA 访问规则:

  1. 从那一刻起,不应调用其他 key writing 函数 获取指针,始终使用 DMA 访问 读取或修改字符串。

  2. 每次RedisModule_StringTruncate()以继续执行 DMA 访问RedisModule_StringDMA()应再次调用以重新获取 新的 Pointer 和 Length。

  3. 如果返回的指针不为 NULL,但长度为零,则 no byte 可以被触及(字符串为空,或者 key 本身为空) 所以一个RedisModule_StringTruncate()如果要放大,则应使用 call 字符串,然后再次调用 StringDMA() 以获取指针。

RedisModule_StringTruncate

int RedisModule_StringTruncate(RedisModuleKey *key, size_t newlen);

从以下版本可用: 4.0.0

如果键是开放的,可以写入并且是字符串类型,请调整它的大小,填充 如果新长度大于旧长度,则为零字节。

通话结束后,RedisModule_StringDMA()必须再次调用才能继续 使用新指针进行 DMA 访问。

该函数返回REDISMODULE_OK成功时,以及REDISMODULE_ERR上 error,即 key 未打开写入,不是字符串 或要求调整大小超过 512 MB。

如果 key 为空,则使用新的 string 值创建一个字符串 key 除非请求的新 Length 值为零。

列表类型的关键 API

许多列表函数通过索引访问元素。由于列表位于 本质上是一个双向链表,通过索引访问元素通常是一个 O(N)作。但是,如果元素按顺序访问或使用 索引,则函数经过优化以从 前一个索引,而不是从列表的末尾查找。

这使得可以使用简单的 for 循环高效地完成迭代:

long n = RedisModule_ValueLength(key);
for (long i = 0; i < n; i++) {
    RedisModuleString *elem = RedisModule_ListGet(key, i);
    // Do stuff...
}

请注意,在使用RedisModule_ListPop,RedisModule_ListSetRedisModule_ListInsert,则内部迭代器将失效,因此下一个作 将需要线性查找。

以任何其他方式修改列表,例如使用RedisModule_Call(),而键 is open 会混淆内部迭代器,如果 key 在此类修改之后使用。在这种情况下,必须重新打开密钥。

另请参阅RedisModule_ValueLength(),它返回列表的长度。

RedisModule_ListPush

int RedisModule_ListPush(RedisModuleKey *key,
                         int where,
                         RedisModuleString *ele);

从以下版本可用: 4.0.0

将元素推送到列表中,根据 'where' 参数在 head 或 tail 上 (REDISMODULE_LIST_HEADREDISMODULE_LIST_TAIL).如果该键引用 empty key opened for writing,则创建 key。成功后,REDISMODULE_OK返回。失败时,REDISMODULE_ERR返回errno设置为 遵循:

  • 如果 key 或 ele 为 NULL,则为 EINVAL。
  • ENOTSUP 如果键是 list 以外的其他类型。
  • EBADF 如果未打开密钥进行写入。

注意:在 Redis 7.0 之前,errno未由此函数设置。

RedisModule_ListPop

RedisModuleString *RedisModule_ListPop(RedisModuleKey *key, int where);

从以下版本可用: 4.0.0

从列表中弹出一个元素,并将其作为模块字符串对象返回 用户应该可以自由使用RedisModule_FreeString()或通过启用 自动记忆。这whereargument 指定元素是否应为 从列表的开头或结尾弹出 (REDISMODULE_LIST_HEADREDISMODULE_LIST_TAIL).失败时,该命令返回 NULL 并将errno如下:

  • 如果 key 为 NULL,则为 EINVAL。
  • ENOTSUP 如果键为空或属于 list 以外的其他类型。
  • EBADF 如果未打开密钥进行写入。

注意:在 Redis 7.0 之前,errno未由此函数设置。

RedisModule_ListGet

RedisModuleString *RedisModule_ListGet(RedisModuleKey *key, long index);

从以下版本可用: 7.0.0

返回索引处的元素index在列表中存储的key,就像 LINDEX 命令。该元素应该使用RedisModule_FreeString()或使用 自动内存管理。

索引从零开始,因此 0 表示第一个元素,1 表示第二个元素 等等。负索引可用于指定从 列表的尾部。这里,-1 表示最后一个元素,-2 表示倒数第二个元素 等等。

如果在给定的键和索引中找不到值,则返回 NULL 并errno设置如下:

  • 如果 key 为 NULL,则为 EINVAL。
  • ENOTSUP 如果键不是列表。
  • EBADF(如果密钥未打开以供读取)。
  • EDOM(如果索引在列表中不是有效索引)。

RedisModule_ListSet

int RedisModule_ListSet(RedisModuleKey *key,
                        long index,
                        RedisModuleString *value);

从以下版本可用: 7.0.0

替换索引处的元素index在列表中存储的key.

索引从零开始,因此 0 表示第一个元素,1 表示第二个元素 等等。负索引可用于指定从 列表的尾部。这里,-1 表示最后一个元素,-2 表示倒数第二个元素 等等。

成功后,REDISMODULE_OK返回。失败时,REDISMODULE_ERR是 returned 和errno设置如下:

  • 如果 key 或 value 为 NULL,则为 EINVAL。
  • ENOTSUP 如果键不是列表。
  • EBADF 如果未打开密钥进行写入。
  • EDOM(如果索引在列表中不是有效索引)。

RedisModule_ListInsert

int RedisModule_ListInsert(RedisModuleKey *key,
                           long index,
                           RedisModuleString *value);

从以下版本可用: 7.0.0

在给定索引处插入元素。

索引从零开始,因此 0 表示第一个元素,1 表示第二个元素 等等。负索引可用于指定从 列表的尾部。这里,-1 表示最后一个元素,-2 表示倒数第二个元素 等等。索引是插入元素后的索引。

成功后,REDISMODULE_OK返回。失败时,REDISMODULE_ERR是 returned 和errno设置如下:

  • 如果 key 或 value 为 NULL,则为 EINVAL。
  • ENOTSUP 如果 name 是 list 的其他类型的键。
  • EBADF 如果未打开密钥进行写入。
  • EDOM(如果索引在列表中不是有效索引)。

RedisModule_ListDelete

int RedisModule_ListDelete(RedisModuleKey *key, long index);

从以下版本可用: 7.0.0

删除给定索引处的元素。索引从 0 开始。负指数 也可以使用,从列表的末尾开始计数。

成功后,REDISMODULE_OK返回。失败时,REDISMODULE_ERR是 returned 和errno设置如下:

  • 如果 key 或 value 为 NULL,则为 EINVAL。
  • ENOTSUP 如果键不是列表。
  • EBADF 如果未打开密钥进行写入。
  • EDOM(如果索引在列表中不是有效索引)。

有序集类型的关键 API

另请参阅RedisModule_ValueLength(),它返回排序集的长度。

RedisModule_ZsetAdd

int RedisModule_ZsetAdd(RedisModuleKey *key,
                        double score,
                        RedisModuleString *ele,
                        int *flagsptr);

从以下版本可用: 4.0.0

将新元素添加到具有指定 'score' 的排序集中。 如果该元素已存在,则更新分数。

如果 key 是空的 open key,则在 value 处创建一个新的排序集 编写设置。

可以通过指针将其他标志传递给函数,标志 都用于接收输入,并在函数 返回。如果不使用特殊标志,'flagsptr' 可以为 NULL。

输入标志包括:

REDISMODULE_ZADD_XX: Element must already exist. Do nothing otherwise.
REDISMODULE_ZADD_NX: Element must not exist. Do nothing otherwise.
REDISMODULE_ZADD_GT: If element exists, new score must be greater than the current score. 
                     Do nothing otherwise. Can optionally be combined with XX.
REDISMODULE_ZADD_LT: If element exists, new score must be less than the current score.
                     Do nothing otherwise. Can optionally be combined with XX.

输出标志为:

REDISMODULE_ZADD_ADDED: The new element was added to the sorted set.
REDISMODULE_ZADD_UPDATED: The score of the element was updated.
REDISMODULE_ZADD_NOP: No operation was performed because XX or NX flags.

成功后,函数返回REDISMODULE_OK.在以下错误上REDISMODULE_ERR返回:

  • 未打开密钥进行写入。
  • 密钥的类型错误。
  • 'score' double 值不是数字 (NaN)。

RedisModule_ZsetIncrby

int RedisModule_ZsetIncrby(RedisModuleKey *key,
                           double score,
                           RedisModuleString *ele,
                           int *flagsptr,
                           double *newscore);

从以下版本可用: 4.0.0

这个函数的工作原理与RedisModule_ZsetAdd(),而不是设置 new score 时,现有元素的 score 将递增,或者如果 元素不存在,则假设旧 score 为 零。

input 和 output 标志以及返回值具有相同的 这意味着,此函数将返回的唯一区别REDISMODULE_ERR即使 'score' 是一个有效的双倍数,但将其添加到 添加到现有分数中,则转换为 NaN(非数字)条件。

此函数有一个附加字段 'newscore',如果不是填写 NULL 替换为增量后元素的新 score(如果没有错误) 返回。

RedisModule_ZsetRem

int RedisModule_ZsetRem(RedisModuleKey *key,
                        RedisModuleString *ele,
                        int *deleted);

从以下版本可用: 4.0.0

从排序集中删除指定的元素。 该函数返回REDISMODULE_OK成功时,以及REDISMODULE_ERR满足以下条件之一:

  • 未打开密钥进行写入。
  • 密钥的类型错误。

返回值并不表示元素确实是 删除(因为它存在)或未删除,只是如果函数被执行 取得了成功。

为了知道元素是否已被删除,附加参数 必须传递 'deleted',它通过引用填充整数 根据作的结果将其设置为 1 或 0。 如果调用方不感兴趣,则 'deleted' 参数可以为 NULL 了解该元素是否真的被删除。

空键将通过不执行任何作来正确处理。

RedisModule_ZsetScore

int RedisModule_ZsetScore(RedisModuleKey *key,
                          RedisModuleString *ele,
                          double *score);

从以下版本可用: 4.0.0

成功后,检索在有序集元素处关联的双倍分数 'ele' 并返回REDISMODULE_OK.否则REDISMODULE_ERR返回 以发出以下条件之一的信号:

  • 排序集中没有这样的元素 'ele' 。
  • 键不是有序集。
  • 该 key 是一个打开的空 key。

Sorted Set 迭代器的关键 API

RedisModule_ZsetRangeStop

void RedisModule_ZsetRangeStop(RedisModuleKey *key);

从以下版本可用: 4.0.0

停止有序集迭代。

RedisModule_ZsetRangeEndReached

int RedisModule_ZsetRangeEndReached(RedisModuleKey *key);

从以下版本可用: 4.0.0

返回 “End of range” 标志值以表示迭代结束。

RedisModule_ZsetFirstInScoreRange

int RedisModule_ZsetFirstInScoreRange(RedisModuleKey *key,
                                      double min,
                                      double max,
                                      int minex,
                                      int maxex);

从以下版本可用: 4.0.0

设置一个排序集迭代器,查找指定 范围。返回REDISMODULE_OK如果 Iterator 已正确初始化 否则REDISMODULE_ERR在以下条件下返回:

  1. 存储在 key 的值不是有序集或 key 为空。

范围根据两个双精度值 'min' 和 'max' 指定。 使用以下两个宏,两者都可以是无限的:

  • REDISMODULE_POSITIVE_INFINITE对于正无限价值
  • REDISMODULE_NEGATIVE_INFINITE对于负无限值

'minex' 和 'maxex' 参数(如果为 true)分别设置一个范围 其中 min 和 max 值是互斥的(不包括在内),而不是 包容。

RedisModule_ZsetLastInScoreRange

int RedisModule_ZsetLastInScoreRange(RedisModuleKey *key,
                                     double min,
                                     double max,
                                     int minex,
                                     int maxex);

从以下版本可用: 4.0.0

完全一样RedisModule_ZsetFirstInScoreRange()但是 而是为迭代的开始选择范围。

RedisModule_ZsetFirstInLexRange

int RedisModule_ZsetFirstInLexRange(RedisModuleKey *key,
                                    RedisModuleString *min,
                                    RedisModuleString *max);

从以下版本可用: 4.0.0

设置一个排序集迭代器,查找指定 词典范围。返回REDISMODULE_OK如果迭代器正确 否则初始化REDISMODULE_ERR在 以下条件:

  1. 存储在 key 的值不是有序集或 key 为空。
  2. 字典范围“min”和“max”格式无效。

'min' 和 'max' 应为 2RedisModuleString对象 格式与传递给 ZRANGEBYLEX 命令的参数相同。 该函数不获取对象的所有权,因此可以释放它们 设置迭代器后尽快。

RedisModule_ZsetLastInLexRange

int RedisModule_ZsetLastInLexRange(RedisModuleKey *key,
                                   RedisModuleString *min,
                                   RedisModuleString *max);

从以下版本可用: 4.0.0

完全一样RedisModule_ZsetFirstInLexRange()但是 而是为迭代的开始选择范围。

RedisModule_ZsetRangeCurrentElement

RedisModuleString *RedisModule_ZsetRangeCurrentElement(RedisModuleKey *key,
                                                       double *score);

从以下版本可用: 4.0.0

返回活动有序集迭代器的当前有序集元素 如果迭代器中指定的范围不包含任何 元素。

RedisModule_ZsetRangeNext

int RedisModule_ZsetRangeNext(RedisModuleKey *key);

从以下版本可用: 4.0.0

转到排序集迭代器的下一个元素。如果有,则返回 1 下一个元素,如果我们已经在最新的元素或范围 根本不包括任何物品。

RedisModule_ZsetRangePrev

int RedisModule_ZsetRangePrev(RedisModuleKey *key);

从以下版本可用: 4.0.0

转到有序集迭代器的上一个元素。如果有,则返回 1 前一个元素,如果我们已经在第一个元素或范围 根本不包括任何物品。

哈希类型的关键 API

另请参阅RedisModule_ValueLength(),它返回哈希中的字段数。

RedisModule_HashSet

int RedisModule_HashSet(RedisModuleKey *key, int flags, ...);

从以下版本可用: 4.0.0

将指定 hash 字段的字段设置为指定值。 如果 key 是打开用于写入的空 key,则使用 empty hash 值,以便设置指定的字段。

该函数是可变参数的,用户必须指定字段对 names 和 values 的RedisModuleStringpointers(除非 CFIELD 选项,请参阅后面)。在 field/value-ptr 对的末尾, 必须将 NULL 指定为最后一个参数,以表示参数结束 在 variadic 函数中。

将哈希 argv[1] 设置为值 argv[2] 的示例:

 RedisModule_HashSet(key,REDISMODULE_HASH_NONE,argv[1],argv[2],NULL);

该函数还可用于删除字段(如果存在) 通过将它们设置为指定的REDISMODULE_HASH_DELETE:

 RedisModule_HashSet(key,REDISMODULE_HASH_NONE,argv[1],
                     REDISMODULE_HASH_DELETE,NULL);

命令的行为会随着指定的标志而变化,这些标志可以是 设置为REDISMODULE_HASH_NONE如果不需要特殊行为。

REDISMODULE_HASH_NX: The operation is performed only if the field was not
                     already existing in the hash.
REDISMODULE_HASH_XX: The operation is performed only if the field was
                     already existing, so that a new value could be
                     associated to an existing filed, but no new fields
                     are created.
REDISMODULE_HASH_CFIELDS: The field names passed are null terminated C
                          strings instead of RedisModuleString objects.
REDISMODULE_HASH_COUNT_ALL: Include the number of inserted fields in the
                            returned number, in addition to the number of
                            updated and deleted fields. (Added in Redis
                            6.2.)

除非指定 NX,否则该命令将旧字段值覆盖为 新的 。

使用REDISMODULE_HASH_CFIELDS,字段名称使用 普通的 C 字符串,例如要删除字段 “foo” ,请执行以下命令 代码可以使用:

 RedisModule_HashSet(key,REDISMODULE_HASH_CFIELDS,"foo",
                     REDISMODULE_HASH_DELETE,NULL);

返回值:

调用之前哈希中存在的字段数,这些字段已被 updated(其旧值已替换为新值)或 deleted。如果 旗REDISMODULE_HASH_COUNT_ALL已设置,则插入的字段之前未 存在于哈希中也会被计算在内。

如果返回值为零,则errno设置(从 Redis 6.2 开始),如下所示:

  • EINVAL (如果设置了任何未知标志)或 key 为 NULL。
  • ENOTSUP(如果键与非 Hash 值相关联)。
  • EBADF(如果未打开密钥进行写入)。
  • ENOENT,如果未按照上面的 Return value 中所述计算任何字段。 这实际上并不是一个错误。如果所有字段 刚刚创建,并且COUNT_ALL标志未设置,或者保留了更改 back 的 x 和 XX 标志。

注意:此函数的返回值语义差异很大 在 Redis 6.2 和更早版本之间。使用它的模块应该确定 Redis 版本并相应地处理它。

RedisModule_HashGet

int RedisModule_HashGet(RedisModuleKey *key, int flags, ...);

从以下版本可用: 4.0.0

从哈希值获取字段。此函数使用变量 个参数,交替字段名称(作为RedisModuleStringpointer) 替换为指向RedisModuleString指针,该指针设置为 如果字段存在,则为 NULL,如果字段不存在。 在字段/值 ptr 对的末尾,必须将 NULL 指定为 last argument 来表示可变参数函数中参数的结束。

下面是一个示例用法:

 RedisModuleString *first, *second;
 RedisModule_HashGet(mykey,REDISMODULE_HASH_NONE,argv[1],&first,
                     argv[2],&second,NULL);

与 一样RedisModule_HashSet()可以指定命令的行为 传递不同于REDISMODULE_HASH_NONE:

REDISMODULE_HASH_CFIELDS:字段名称作为以 null 结尾的 C 字符串。

REDISMODULE_HASH_EXISTS:而不是设置字段的值 期望RedisModuleStringpointer 到 Pointer 的 Pointer 中,函数只是 报告字段是否存在,并需要一个整数指针 作为每对的第二个元素。

示例REDISMODULE_HASH_CFIELDS:

 RedisModuleString *username, *hashedpass;
 RedisModule_HashGet(mykey,REDISMODULE_HASH_CFIELDS,"username",&username,"hp",&hashedpass, NULL);

示例REDISMODULE_HASH_EXISTS:

 int exists;
 RedisModule_HashGet(mykey,REDISMODULE_HASH_EXISTS,argv[1],&exists,NULL);

该函数返回REDISMODULE_OKon success 和REDISMODULE_ERR如果 键不是哈希值。

内存管理:

返回的RedisModuleString对象应与RedisModule_FreeString(),或者通过启用自动内存管理。

Stream 类型的关键 API

有关流的介绍,请参阅 https://redis.io/topics/streams-intro

类型RedisModuleStreamID,用于流函数,是一个结构 具有两个 64 位字段,定义为

typedef struct RedisModuleStreamID {
    uint64_t ms;
    uint64_t seq;
} RedisModuleStreamID;

另请参阅RedisModule_ValueLength(),它返回流的长度,而 转换函数RedisModule_StringToStreamID()RedisModule_CreateStringFromStreamID().

RedisModule_StreamAdd

int RedisModule_StreamAdd(RedisModuleKey *key,
                          int flags,
                          RedisModuleStreamID *id,
                          RedisModuleString **argv,
                          long numfields);

从以下版本可用: 6.2.0

向流中添加一个条目。就像没有修剪的 XADD 一样。

  • key:存储(或将要)存储流的键
  • flags:一个
    • REDISMODULE_STREAM_ADD_AUTOID:自动分配流 ID,就像在 XADD 命令中一样。*
  • id:如果AUTOID标志,这是分配的 ID 所在的位置 返回。如果AUTOID已设置,如果您不想接收 ID。如果AUTOID未设置,则这是请求的 ID。
  • argv:指向大小为numfields * 2包含 fields 和 values。
  • numfields:中的 字段-值对数argv.

返回REDISMODULE_OK如果已添加条目。失败时,REDISMODULE_ERR返回errno设置如下:

  • EINVAL 如果使用无效参数调用
  • ENOTSUP(如果键引用 stream 以外的类型的值)
  • EBADF(如果未打开键进行写入)
  • EDOM 中,如果给定的 ID 为 0-0 或不大于 stream (仅当未设置 AUTOID 标志时)
  • EFBIG(如果流已达到最后一个可能的 ID)
  • ERANGE(如果元素太大而无法存储)。

RedisModule_StreamDelete

int RedisModule_StreamDelete(RedisModuleKey *key, RedisModuleStreamID *id);

从以下版本可用: 6.2.0

从流中删除条目。

  • key:打开用于写入的密钥,未启动流迭代器。
  • id:要删除的条目的流 ID。

返回REDISMODULE_OK成功。失败时,REDISMODULE_ERR返回 和errno设置如下:

  • EINVAL 如果使用无效参数调用
  • ENOTSUP,如果键引用了 stream 以外的类型的值,或者 key 为空
  • EBADF(如果键未打开进行写入或流迭代器为 关联键
  • ENOENT,如果不存在具有给定流 ID 的条目

另请参阅RedisModule_StreamIteratorDelete()删除当前条目,而 使用 Stream 迭代器进行迭代。

RedisModule_StreamIteratorStart

int RedisModule_StreamIteratorStart(RedisModuleKey *key,
                                    int flags,
                                    RedisModuleStreamID *start,
                                    RedisModuleStreamID *end);

从以下版本可用: 6.2.0

设置流迭代器。

  • key:使用RedisModule_OpenKey().
  • flags:
    • REDISMODULE_STREAM_ITERATOR_EXCLUSIVE:不包括startend在迭代范围内。
    • REDISMODULE_STREAM_ITERATOR_REVERSE:以相反的顺序迭代,启动 从end的范围。
  • start:范围的下限。使用 NULL 作为 流。
  • end:范围的上限。使用 NULL 作为流的结尾。

返回REDISMODULE_OK成功。失败时,REDISMODULE_ERR返回 和errno设置如下:

  • EINVAL 如果使用无效参数调用
  • ENOTSUP,如果键引用了 stream 以外的类型的值,或者 key 为空
  • EBADF(如果键未打开进行写入或流迭代器为 已与密钥关联
  • 如果 EDOMstartend超出有效范围

返回REDISMODULE_OKon success 和REDISMODULE_ERR如果密钥没有 引用流,或者如果给出了无效的参数。

流 ID 是使用RedisModule_StreamIteratorNextID()和 对于每个流 ID,字段和值是使用RedisModule_StreamIteratorNextField().通过调用RedisModule_StreamIteratorStop().

示例(省略错误处理):

RedisModule_StreamIteratorStart(key, 0, startid_ptr, endid_ptr);
RedisModuleStreamID id;
long numfields;
while (RedisModule_StreamIteratorNextID(key, &id, &numfields) ==
       REDISMODULE_OK) {
    RedisModuleString *field, *value;
    while (RedisModule_StreamIteratorNextField(key, &field, &value) ==
           REDISMODULE_OK) {
        //
        // ... Do stuff ...
        //
        RedisModule_FreeString(ctx, field);
        RedisModule_FreeString(ctx, value);
    }
}
RedisModule_StreamIteratorStop(key);

RedisModule_StreamIteratorStop

int RedisModule_StreamIteratorStop(RedisModuleKey *key);

从以下版本可用: 6.2.0

停止使用RedisModule_StreamIteratorStart()和 重新获得记忆。

返回REDISMODULE_OK成功。失败时,REDISMODULE_ERR返回 和errno设置如下:

  • EINVAL(如果使用 NULL 键调用)
  • ENOTSUP,如果键引用了 stream 以外的类型的值,或者 key 为空
  • EBADF(如果未打开键进行写入或没有流迭代器) 关联键

RedisModule_StreamIteratorNextID

int RedisModule_StreamIteratorNextID(RedisModuleKey *key,
                                     RedisModuleStreamID *id,
                                     long *numfields);

从以下版本可用: 6.2.0

查找下一个流条目,并返回其流 ID 和 领域。

  • key:流迭代器已开始使用的键RedisModule_StreamIteratorStart().
  • id:返回的流 ID。如果您不在乎,则为 NULL。
  • numfields:找到的流条目中的字段数。如果 NULL 不在乎。

返回REDISMODULE_OK和集*id*numfields如果找到条目。 失败时,REDISMODULE_ERR返回errno设置如下:

  • EINVAL(如果使用 NULL 键调用)
  • ENOTSUP,如果键引用了 stream 以外的类型的值,或者 key 为空
  • EBADF(如果没有流迭代器与键关联)
  • ENOENT(如果迭代器的范围内没有更多条目)

在实践中,如果RedisModule_StreamIteratorNextID()在成功调用后调用 自RedisModule_StreamIteratorStart()并且使用相同的密钥,可以安全地假设 一REDISMODULE_ERRreturn value 表示没有更多条目。

RedisModule_StreamIteratorNextField()以检索字段和值。 请参阅以下示例RedisModule_StreamIteratorStart().

RedisModule_StreamIteratorNextField

int RedisModule_StreamIteratorNextField(RedisModuleKey *key,
                                        RedisModuleString **field_ptr,
                                        RedisModuleString **value_ptr);

从以下版本可用: 6.2.0

获取当前流 ID 的 next 字段及其对应的值 在流迭代中。调用RedisModule_StreamIteratorNextID()以获取每个字段-值对。

  • key:流迭代器已启动的键。
  • field_ptr:这是返回字段的位置。
  • value_ptr:这是返回值的位置。

返回REDISMODULE_OK和点数*field_ptr*value_ptr到 Freshly 分配RedisModuleString对象。字符串对象被释放 如果启用了自动内存,则在回调完成时自动调用。上 失败REDISMODULE_ERR返回errno设置如下:

  • EINVAL(如果使用 NULL 键调用)
  • ENOTSUP,如果键引用了 stream 以外的类型的值,或者 key 为空
  • EBADF(如果没有流迭代器与键关联)
  • ENOENT(如果当前流条目中没有更多字段)

在实践中,如果RedisModule_StreamIteratorNextField()在成功后调用 调用RedisModule_StreamIteratorNextID()并且使用相同的密钥,可以安全地假设 那个REDISMODULE_ERRreturn value 表示没有更多字段。

请参阅以下示例RedisModule_StreamIteratorStart().

RedisModule_StreamIteratorDelete

int RedisModule_StreamIteratorDelete(RedisModuleKey *key);

从以下版本可用: 6.2.0

在迭代时删除当前流条目。

此函数可以在RedisModule_StreamIteratorNextID()或任何 调用RedisModule_StreamIteratorNextField().

返回REDISMODULE_OK成功。失败时,REDISMODULE_ERR返回 和errno设置如下:

  • 如果 key 为 NULL,则为 EINVAL
  • ENOTSUP(如果键为空或属于 stream 以外的其他类型)
  • EBADF(如果未打开键进行写入),如果未启动迭代器
  • 如果迭代器没有当前流条目,则为 ENOENT

RedisModule_StreamTrimByLength

long long RedisModule_StreamTrimByLength(RedisModuleKey *key,
                                         int flags,
                                         long long length);

从以下版本可用: 6.2.0

按长度修剪流,类似于使用 MAXLEN 的 XTRIM。

  • key:打开密钥进行写入。
  • flags:的位域
    • REDISMODULE_STREAM_TRIM_APPROX:如果提高性能,则减少修剪, 例如带有 .~
  • length:修剪后要保留的流条目数。

返回已删除的条目数。失败时,负值为 returned 和errno设置如下:

  • EINVAL 如果使用无效参数调用
  • ENOTSUP(如果键为空或类型不是 stream)
  • EBADF(如果密钥未打开进行写入)

RedisModule_StreamTrimByID

long long RedisModule_StreamTrimByID(RedisModuleKey *key,
                                     int flags,
                                     RedisModuleStreamID *id);

从以下版本可用: 6.2.0

按 ID 修剪流,类似于使用 MIN 的 XTRIM。

  • key:打开密钥进行写入。
  • flags:的位域
    • REDISMODULE_STREAM_TRIM_APPROX:如果提高性能,则减少修剪, 例如带有 .~
  • id:修剪后要保留的最小流 ID。

返回已删除的条目数。失败时,负值为 returned 和errno设置如下:

  • EINVAL 如果使用无效参数调用
  • ENOTSUP(如果键为空或类型不是 stream)
  • EBADF(如果密钥未打开进行写入)

从模块调用 Redis 命令

RedisModule_Call()向 Redis 发送命令。其余函数处理回复。

RedisModule_FreeCallReply

void RedisModule_FreeCallReply(RedisModuleCallReply *reply);

从以下版本可用: 4.0.0

释放 Call 回复及其包含的所有嵌套回复(如果它是 数组。

RedisModule_CallReplyType

int RedisModule_CallReplyType(RedisModuleCallReply *reply);

从以下版本可用: 4.0.0

将回复类型返回为以下类型之一:

  • REDISMODULE_REPLY_UNKNOWN
  • REDISMODULE_REPLY_STRING
  • REDISMODULE_REPLY_ERROR
  • REDISMODULE_REPLY_INTEGER
  • REDISMODULE_REPLY_ARRAY
  • REDISMODULE_REPLY_NULL
  • REDISMODULE_REPLY_MAP
  • REDISMODULE_REPLY_SET
  • REDISMODULE_REPLY_BOOL
  • REDISMODULE_REPLY_DOUBLE
  • REDISMODULE_REPLY_BIG_NUMBER
  • REDISMODULE_REPLY_VERBATIM_STRING
  • REDISMODULE_REPLY_ATTRIBUTE
  • REDISMODULE_REPLY_PROMISE

RedisModule_CallReplyLength

size_t RedisModule_CallReplyLength(RedisModuleCallReply *reply);

从以下版本可用: 4.0.0

返回回复类型长度(如果适用)。

RedisModule_CallReplyArrayElement

RedisModuleCallReply *RedisModule_CallReplyArrayElement(RedisModuleCallReply *reply,
                                                        size_t idx);

从以下版本可用: 4.0.0

返回数组 reply 的第 'idx' 个嵌套 call reply 元素,或 NULL 如果 reply type 错误或索引超出范围。

RedisModule_CallReplyInteger

long long RedisModule_CallReplyInteger(RedisModuleCallReply *reply);

从以下版本可用: 4.0.0

返回long long的整数回复。

RedisModule_CallReplyDouble

double RedisModule_CallReplyDouble(RedisModuleCallReply *reply);

从以下版本可用: 7.0.0

返回 double 回复的 double 值。

RedisModule_CallReplyBigNumber

const char *RedisModule_CallReplyBigNumber(RedisModuleCallReply *reply,
                                           size_t *len);

从以下版本可用: 7.0.0

返回 big number 回复的 big number 值。

RedisModule_CallReplyVerbatim

const char *RedisModule_CallReplyVerbatim(RedisModuleCallReply *reply,
                                          size_t *len,
                                          const char **format);

从以下版本可用: 7.0.0

返回逐字字符串回复的值, 可以给出一个可选的 output 参数来获取逐字回复格式。

RedisModule_CallReplyBool

int RedisModule_CallReplyBool(RedisModuleCallReply *reply);

从以下版本可用: 7.0.0

返回布尔应答的布尔值。

RedisModule_CallReplySetElement

RedisModuleCallReply *RedisModule_CallReplySetElement(RedisModuleCallReply *reply,
                                                      size_t idx);

从以下版本可用: 7.0.0

返回集合回复的第 'idx' 个嵌套调用 reply 元素,或 NULL 如果 reply type 错误或索引超出范围。

RedisModule_CallReplyMapElement

int RedisModule_CallReplyMapElement(RedisModuleCallReply *reply,
                                    size_t idx,
                                    RedisModuleCallReply **key,
                                    RedisModuleCallReply **val);

从以下版本可用: 7.0.0

检索 map 回复的第 'idx' 个键和值。

返回:

  • REDISMODULE_OK成功。
  • REDISMODULE_ERR如果 idx 超出范围或回复类型错误。

keyvaluearguments 用于通过引用返回,并且可能是 如果不需要,则为 NULL。

RedisModule_CallReplyAttribute

RedisModuleCallReply *RedisModule_CallReplyAttribute(RedisModuleCallReply *reply);

从以下版本可用: 7.0.0

返回给定回复的属性,如果不存在属性,则返回 NULL。

RedisModule_CallReplyAttributeElement

int RedisModule_CallReplyAttributeElement(RedisModuleCallReply *reply,
                                          size_t idx,
                                          RedisModuleCallReply **key,
                                          RedisModuleCallReply **val);

从以下版本可用: 7.0.0

检索属性回复的第 'idx' 个键和值。

返回:

  • REDISMODULE_OK成功。
  • REDISMODULE_ERR如果 idx 超出范围或回复类型错误。

keyvaluearguments 用于通过引用返回,并且可能是 如果不需要,则为 NULL。

RedisModule_CallReplyPromiseSetUnblockHandler

void RedisModule_CallReplyPromiseSetUnblockHandler(RedisModuleCallReply *reply,
                                                   RedisModuleOnUnblocked on_unblock,
                                                   void *private_data);

从以下版本可用: 7.2.0

在给定的 promise 上设置 unblock 处理程序 (callback 和 private data)RedisModuleCallReply. 给定的回复必须是 promise 类型 (REDISMODULE_REPLY_PROMISE).

RedisModule_CallReplyPromiseAbort

int RedisModule_CallReplyPromiseAbort(RedisModuleCallReply *reply,
                                      void **private_data);

从以下版本可用: 7.2.0

中止给定 Promise 的执行RedisModuleCallReply. 返回REDMODULE_OK如果 abort 成功完成并且REDISMODULE_ERR如果无法中止执行 (execution already finished)。 如果执行中止 (REDMODULE_OK被返回),则private_dataout 参数 将设置为在 'RedisModule_CallReplyPromiseSetUnblockHandler' 因此,调用方将能够释放私有数据。

如果成功中止执行,则承诺不会调用 unblock 处理程序。 也就是说,abort作可能会成功,但作仍将继续。 例如,如果一个模块实现了一些阻塞命令并且不遵守 断开连接回调。对于纯 Redis 命令,这不会发生。

RedisModule_CallReplyStringPtr

const char *RedisModule_CallReplyStringPtr(RedisModuleCallReply *reply,
                                           size_t *len);

从以下版本可用: 4.0.0

返回字符串或错误回复的指针和长度。

RedisModule_CreateStringFromCallReply

RedisModuleString *RedisModule_CreateStringFromCallReply(RedisModuleCallReply *reply);

从以下版本可用: 4.0.0

从类型为 string、error 或 整数。否则 (错误的回复类型) 返回 NULL。

RedisModule_SetContextUser

void RedisModule_SetContextUser(RedisModuleCtx *ctx,
                                const RedisModuleUser *user);

从以下版本可用: 7.0.6

修改RedisModule_Call将使用(例如,用于 ACL 检查)

RedisModule_Call

RedisModuleCallReply *RedisModule_Call(RedisModuleCtx *ctx,
                                       const char *cmdname,
                                       const char *fmt,
                                       ...);

从以下版本可用: 4.0.0

导出的 API 以从模块调用任何 Redis 命令。

  • cmdname:要调用的 Redis 命令。

  • fmt:命令参数的格式说明符字符串。每 的参数应由有效的类型规范指定。这 格式说明符也可以包含修饰符!,A,3R哪 没有相应的参数。

    • b-- 参数是一个缓冲区,紧跟着另一个 参数,该参数是缓冲区的长度。

    • c-- 参数是指向纯 C 字符串(以 null 结尾)的指针。

    • l-- 参数是一个long long整数。

    • s-- 参数是 RedisModuleString。

    • v-- 参数是 RedisModuleString 的向量。

    • !-- 将 Redis 命令及其参数发送到副本和 AOF。

    • A-- 抑制 AOF 传播,仅发送到副本(需要!).

    • R-- 抑制副本传播,仅发送到 AOF(需要!).

    • 3-- 返回 RESP3 回复。这将更改命令回复。 例如,HGETALL 返回 map 而不是 flat 数组。

    • 0-- 以 auto 模式返回回复,即回复格式将为 与附加到给定 RedisModuleCtx 的客户端相同。这将 当你想将回复直接传递给客户端时,可能会用到。

    • C-- 以附加到上下文的用户身份运行命令。 用户要么通过客户端自动附加,该客户端直接 发出命令并创建上下文或通过 RedisModule_SetContextUser。 如果上下文不是由发出的命令直接创建的(例如 background 上下文,并且没有通过 RedisModule_SetContextUser 在其上设置用户, RedisModule_Call 将失败。 根据 ACL 规则和原因检查命令是否可以执行 命令以确定的用户身份运行,以便任何将来的用户 依赖活动(例如脚本中的 ACL 检查)将作为 预期。 否则,该命令将以 Redis 不受限制的用户身份运行。

    • S-- 以脚本模式运行命令,这意味着它将引发 如果脚本中不允许的命令,则出错 (标有deny-scriptflag) 调用(如 SHUTDOWN)。 此外,在脚本模式下,如果存在 没有足够的好副本(如min-replicas-to-write) 或者当服务器无法持久保存到磁盘时。

    • W-- 不允许运行任何写入命令(标有write标志)。

    • M-- 不允许deny-oom标记的命令。

    • E-- 将错误返回为 RedisModuleCallReply。如果之前有错误 调用该命令时,将使用 errno 机制返回错误。 此标志还允许将错误作为错误 CallReply 获取 相关的错误消息。

    • 'D' -- 一种 “Dry Run” 模式。return 之前执行底层 call()。 如果一切都成功了,它将返回 NULL,否则它将 return 中包含一个表示错误的 CallReply 对象,就像它是使用 'E' 代码。

    • 'K' -- 允许运行阻塞命令。如果启用并且命令被阻止,则 将返回特殊REDISMODULE_REPLY_PROMISE。此回复类型 表示命令被阻止,并且将异步给出回复。 该模块可以使用此 reply 对象来设置一个处理程序,该处理程序将在 使用 RedisModule_CallReplyPromiseSetUnblockHandler 取消阻止该命令。 处理程序必须在命令调用后立即设置(不要释放 介于两者之间的 Redis 锁)。如果未设置处理程序,则 blocking 命令将 仍然继续执行,但回复将被忽略(fire 和 forget), 请注意,这在角色更改的情况下很危险,如下所述。 该模块可以使用 RedisModule_CallReplyPromiseAbort 中止命令调用 如果尚未完成(有关更多信息,请参阅 RedisModule_CallReplyPromiseAbort 文档 详细信息)。该模块还负责在角色更改时中止执行,方法是使用 server 事件(以便在实例成为副本时收到通知)或依赖于断开连接 callback 的调用。否则可能会导致对副本执行写入作。 与其他调用回复不同,承诺调用 回复必须在 Redis GIL 锁定时释放。 请注意,在解除阻塞时,唯一的 promise 是将调用 unblock 处理程序 如果阻塞RedisModule_Call导致模块也阻塞了一些真实的客户端(使用 RedisModule_BlockClient), 在 UNBLOCK 处理程序上取消阻止此客户端是模块的责任。 在取消阻止处理程序上,只允许执行以下作: * 使用 RedisModule_Call 调用其他 Redis 命令 * 使用 RedisModule_OpenKey 打开密钥 * 将数据复制到副本或 AOF

         Specifically, it is not allowed to call any Redis module API which are client related such as:
         * RedisModule_Reply* API's
         * RedisModule_BlockClient
         * RedisModule_GetCurrentUserName
      
  • ...: Redis 命令的实际参数。

成功时RedisModuleCallReplyobject 返回,否则 返回 NULL 并将 errno 设置为以下值:

  • EBADF:格式说明符错误。
  • EINVAL:错误的命令 arity。
  • ENOENT: 命令不存在。
  • EPERM:在 Cluster 实例中作,key 在非本地 slot 中。
  • EROFS:发送写入命令时在 Cluster 实例中的作 处于只读状态。
  • ENETDOWN:当 cluster 宕机时,在 Cluster 实例中进行作。
  • ENOTSUP:指定模块上下文没有 ACL 用户
  • EACCES:根据 ACL 规则,无法执行命令
  • ENOSPC:不允许使用 Write 或 deny-oom 命令
  • ESPIPE: 脚本模式下不允许使用命令

示例代码片段:

 reply = RedisModule_Call(ctx,"INCRBY","sc",argv[1],"10");
 if (RedisModule_CallReplyType(reply) == REDISMODULE_REPLY_INTEGER) {
   long long myval = RedisModule_CallReplyInteger(reply);
   // Do something with myval.
 }

此 API 记录在此处:https://redis.io/topics/modules-intro

RedisModule_CallReplyProto

const char *RedisModule_CallReplyProto(RedisModuleCallReply *reply,
                                       size_t *len);

从以下版本可用: 4.0.0

返回指向命令返回的协议的指针和长度 返回 Reply 对象。

Modules 数据类型

当字符串 DMA 或使用现有数据结构还不够时,它是 可以从头开始创建新的数据类型并将其导出到 雷迪斯。该模块必须提供一组回调来处理 导出的新值(例如,为了提供 RDB 保存/加载), AOF 重写,依此类推)。在本节中,我们将定义此 API。

RedisModule_CreateDataType

moduleType *RedisModule_CreateDataType(RedisModuleCtx *ctx,
                                       const char *name,
                                       int encver,
                                       void *typemethods_ptr);

从以下版本可用: 4.0.0

注册模块导出的新数据类型。参数是 以后。有关深入的文档,请查看模块 API 文档,尤其是 https://redis.io/docs/latest/develop/reference/modules/modules-native-types/

  • name:一个 9 个字符的数据类型名称,在 Redis 中必须是唯一的 Modules 生态系统。要有创意...并且不会有冲突。用 字符集 A-Z a-z 9-0,加上两个 “-_” 字符。一个好的 idea 是使用,例如<typename>-<vendor>.例如 “tree-AntZ” 可能表示 “@antirez 的树数据结构”。要同时使用两者 小写和大写字母有助于防止冲突。

  • encver:编码版本,即序列化的版本 用于持久保存数据的模块。只要 “name” 匹配项,则 RDB 加载将被分派给类型回调 无论使用什么 'encver',但是模块可以理解 if 它必须加载的编码是旧版本的模块。 例如,模块 “tree-AntZ” 最初使用 encver=0。后 升级后,它开始以不同的格式序列化数据 并使用 encver=1 注册类型。但是,此模块可能会 如果rdb_loadcallback 能够检查 encver 值并采取相应的行动。 encver 必须是介于 0 和 1023 之间的正值。

  • typemethods_ptr 是指向RedisModuleTypeMethods结构 这应该用 Callbacks 和 Structure 方法填充 版,如以下示例所示:

      RedisModuleTypeMethods tm = {
          .version = REDISMODULE_TYPE_METHOD_VERSION,
          .rdb_load = myType_RDBLoadCallBack,
          .rdb_save = myType_RDBSaveCallBack,
          .aof_rewrite = myType_AOFRewriteCallBack,
          .free = myType_FreeCallBack,
    
          // Optional fields
          .digest = myType_DigestCallBack,
          .mem_usage = myType_MemUsageCallBack,
          .aux_load = myType_AuxRDBLoadCallBack,
          .aux_save = myType_AuxRDBSaveCallBack,
          .free_effort = myType_FreeEffortCallBack,
          .unlink = myType_UnlinkCallBack,
          .copy = myType_CopyCallback,
          .defrag = myType_DefragCallback
    
          // Enhanced optional fields
          .mem_usage2 = myType_MemUsageCallBack2,
          .free_effort2 = myType_FreeEffortCallBack2,
          .unlink2 = myType_UnlinkCallBack2,
          .copy2 = myType_CopyCallback2,
      }
    
  • rdb_load:从 RDB 文件加载数据的回调函数指针。

  • rdb_save:将数据保存到 RDB 文件的回调函数指针。

  • aof_rewrite:将数据重写为命令的回调函数指针。

  • digest:一个回调函数指针,用于DEBUG DIGEST.

  • free:可以释放 type 值的回调函数指针。

  • aux_save:一个回调函数指针,用于将键空间数据保存到 RDB 文件。 'when' 参数是REDISMODULE_AUX_BEFORE_RDBREDISMODULE_AUX_AFTER_RDB.

  • aux_load:从 RDB 文件加载键空间数据的回调函数指针。 似aux_save返回REDISMODULE_OK成功时,否则为 ERR。

  • free_effort:一个回调函数指针,用于确定模块的 内存需要延迟回收。该模块应返回 释放值。例如:将释放多少个指针。请注意,如果它 返回 0,我们将始终执行 async free。

  • unlink:一个回调函数指针,用于通知模块该 key 具有 已被 redis 从 DB 中删除,并且可能很快就会被后台线程释放。请注意, 它不会在 FLUSHALL/FLUSHDB(同步和异步)上调用,并且模块可以使用RedisModuleEvent_FlushDB钩住它。

  • copy:一个回调函数指针,用于复制指定的 key。 该模块应执行指定值的深层复制并返回该值。 此外,还提供了有关源键和目标键名称的提示。 NULL 返回值被视为错误,并且复制作失败。 注意:如果目标 key 存在且被覆盖,则 copy 回调将为 首先调用,然后是对要替换的值的 free 回调。

  • defrag:一个回调函数指针,用于请求模块进行碎片整理 一个键。然后,该模块应该迭代指针并调用相关的RedisModule_Defrag*()函数对指针或复杂类型进行碎片整理。该模块应继续 迭代,只要RedisModule_DefragShouldStop()返回一个零值,并返回一个 如果已完成,则为零值,如果还有更多工作要完成,则为非零值。如果工作更多 需要完成,RedisModule_DefragCursorSet()RedisModule_DefragCursorGet()可用于跟踪 这在不同的调用中有效。 通常,碎片整理机制调用回调是没有时间限制的,因此RedisModule_DefragShouldStop()始终返回零。“后期碎片整理”机制具有 Time limit (时间限制) 和 provides cursor support (提供游标支持) 仅用于确定的键 具有显著的内部复杂性。为了确定这一点,碎片整理机制 使用free_effortcallback 和 'active-defrag-max-scan-fields' 配置指令。 注意:该值作为void**并且该函数需要更新 pointer(如果顶级值指针已进行碎片整理并因此更改)。

  • mem_usage2:类似于mem_usage,但提供RedisModuleKeyOptCtx参数 这样就可以获取 Key Name 和 DB ID 等元信息,以及 这sample_size用于大小估计(请参阅 MEMORY USAGE 命令)。

  • free_effort2:类似于free_effort,但提供RedisModuleKeyOptCtx参数 这样就可以获取 Key Name 和 DB ID 等元信息。

  • unlink2:类似于unlink,但提供RedisModuleKeyOptCtx参数 这样就可以获取 Key Name 和 DB ID 等元信息。

  • copy2:类似于copy,但提供RedisModuleKeyOptCtx参数 以便获取 Key Name 和 DB ID 等元信息。

  • aux_save2:类似于aux_save,但语义变化很小,如果模块 不在此回调上保存任何内容,则有关此 AUX 字段的数据不会写入 RDB,即使模块未加载,也可以加载 RDB。

注意:模块名称 “AAAAAAAAA” 是保留的,会产生错误,它 恰好也很蹩脚。

如果RedisModule_CreateDataType()RedisModule_OnLoad()功能 已经有一个模块注册了一个同名的类型, 或者,如果模块名称或 encver 无效,则返回 NULL。 否则,新类型将注册到 Redis 中,并且 类型RedisModuleType返回:函数的调用者应将 this 引用转换为全局变量,以便将来在 modules 类型 API,因为单个模块可以注册多个类型。 示例代码片段:

 static RedisModuleType *BalancedTreeType;

 int RedisModule_OnLoad(RedisModuleCtx *ctx) {
     // some code here ...
     BalancedTreeType = RedisModule_CreateDataType(...);
 }

RedisModule_ModuleTypeSetValue

int RedisModule_ModuleTypeSetValue(RedisModuleKey *key,
                                   moduleType *mt,
                                   void *value);

从以下版本可用: 4.0.0

如果 key 是开放写入的,则设置指定的模块类型对象 作为键的值,删除旧值(如果有)。 成功时REDISMODULE_OK返回。如果 的密钥未打开 写入或有一个活动的迭代器,REDISMODULE_ERR返回。

RedisModule_ModuleTypeGetType

moduleType *RedisModule_ModuleTypeGetType(RedisModuleKey *key);

从以下版本可用: 4.0.0

RedisModule_KeyType()返回REDISMODULE_KEYTYPE_MODULE上 key 返回存储在 key 中的值的模块类型指针。

如果键为 NULL、未与模块类型关联或为空, 则返回 NULL。

RedisModule_ModuleTypeGetValue

void *RedisModule_ModuleTypeGetValue(RedisModuleKey *key);

从以下版本可用: 4.0.0

RedisModule_KeyType()返回REDISMODULE_KEYTYPE_MODULE上 key 返回存储在 key 中的模块类型低级值,即 它是由用户通过RedisModule_ModuleTypeSetValue().

如果键为 NULL、未与模块类型关联或为空, 则返回 NULL。

RDB 加载和保存功能

RedisModule_IsIOError

int RedisModule_IsIOError(RedisModuleIO *io);

从以下版本可用: 6.0.0

如果任何以前的 IO API 失败,则返回 true。 为Load*API 的REDISMODULE_OPTIONS_HANDLE_IO_ERRORSflag 必须设置为RedisModule_SetModuleOptions第一。

RedisModule_SaveUnsigned

void RedisModule_SaveUnsigned(RedisModuleIO *io, uint64_t value);

从以下版本可用: 4.0.0

将无符号的 64 位值保存到 RDB 文件中。此函数应仅 在rdb_save实现 new 的模块 数据类型。

RedisModule_LoadUnsigned

uint64_t RedisModule_LoadUnsigned(RedisModuleIO *io);

从以下版本可用: 4.0.0

从 RDB 文件加载无符号的 64 位值。此函数应仅 在rdb_load模块实现的方法 新的数据类型。

RedisModule_SaveSigned

void RedisModule_SaveSigned(RedisModuleIO *io, int64_t value);

从以下版本可用: 4.0.0

喜欢RedisModule_SaveUnsigned()但对于有符号的 64 位值。

RedisModule_LoadSigned

int64_t RedisModule_LoadSigned(RedisModuleIO *io);

从以下版本可用: 4.0.0

喜欢RedisModule_LoadUnsigned()但对于有符号的 64 位值。

RedisModule_SaveString

void RedisModule_SaveString(RedisModuleIO *io, RedisModuleString *s);

从以下版本可用: 4.0.0

rdb_savemethod 的 API 中,将 string 放入 RDB 文件中,并将RedisModuleString.

字符串可以稍后加载RedisModule_LoadString()或 其他 Load 系列函数需要内部的序列化字符串 RDB 文件。

RedisModule_SaveStringBuffer

void RedisModule_SaveStringBuffer(RedisModuleIO *io,
                                  const char *str,
                                  size_t len);

从以下版本可用: 4.0.0

喜欢RedisModule_SaveString()但采用原始 C 指针和长度 作为输入。

RedisModule_LoadString

RedisModuleString *RedisModule_LoadString(RedisModuleIO *io);

从以下版本可用: 4.0.0

rdb_loadmethod 中,加载一个字符串 从 RDB 文件中,该文件之前与RedisModule_SaveString()functions 系列。

返回的字符串是新分配的RedisModuleStringobject 和 用户应该在某个时候通过调用RedisModule_FreeString().

如果数据结构未将字符串存储为RedisModuleString对象 类似的功能RedisModule_LoadStringBuffer()可以改用。

RedisModule_LoadStringBuffer

char *RedisModule_LoadStringBuffer(RedisModuleIO *io, size_t *lenptr);

从以下版本可用: 4.0.0

喜欢RedisModule_LoadString()但返回一个堆分配的字符串,该字符串 分配了RedisModule_Alloc(),并且可以调整大小或释放RedisModule_Realloc()RedisModule_Free().

字符串的大小存储在 '*lenptr' 中,如果不是 NULL。 返回的字符串不会自动以 NULL 结尾,而是被加载 与存储在 RDB 文件中完全相同。

RedisModule_SaveDouble

void RedisModule_SaveDouble(RedisModuleIO *io, double value);

从以下版本可用: 4.0.0

rdb_savemethod 的 API 中,将 double 值添加到 RDB 文件中。double 可以是有效数字、NaN 或无穷大。 可以使用RedisModule_LoadDouble().

RedisModule_LoadDouble

double RedisModule_LoadDouble(RedisModuleIO *io);

从以下版本可用: 4.0.0

rdb_save方法,则加载回 double 值保存者RedisModule_SaveDouble().

RedisModule_SaveFloat

void RedisModule_SaveFloat(RedisModuleIO *io, float value);

从以下版本可用: 4.0.0

rdb_savemethod 的 API 中,保存一个浮点数 值添加到 RDB 文件中。float 可以是有效数字、NaN 或无穷大。 可以使用RedisModule_LoadFloat().

RedisModule_LoadFloat

float RedisModule_LoadFloat(RedisModuleIO *io);

从以下版本可用: 4.0.0

rdb_save方法,则加载回 保存的 float 值RedisModule_SaveFloat().

RedisModule_SaveLongDouble

void RedisModule_SaveLongDouble(RedisModuleIO *io, long double value);

从以下版本可用: 6.0.0

rdb_savemethod 的 API 中,保存一个 long double 值添加到 RDB 文件中。double 可以是有效数字、NaN 或无穷大。 可以使用RedisModule_LoadLongDouble().

RedisModule_LoadLongDouble

long double RedisModule_LoadLongDouble(RedisModuleIO *io);

从以下版本可用: 6.0.0

rdb_save方法,则加载回 long double 值保存者RedisModule_SaveLongDouble().

关键摘要 API(DEBUG DIGEST 模块类型的接口)

RedisModule_DigestAddStringBuffer

void RedisModule_DigestAddStringBuffer(RedisModuleDigest *md,
                                       const char *ele,
                                       size_t len);

从以下版本可用: 4.0.0

向摘要中添加一个新元素。此函数可以多次调用 一个接一个的元素,对于构成给定元素的所有元素 数据结构。函数调用后必须跟对RedisModule_DigestEndSequence最终,当所有 always 按给定顺序添加。查看 Redis Modules 数据类型 文档了解更多信息。但是,这是一个使用 Redis 的快速示例 数据类型。

要添加一系列无序元素(例如,在 Redis 中 Set),要使用的模式为:

foreach element {
    AddElement(element);
    EndSequence();
}

因为 Set 没有顺序,所以添加的每个元素都有一个位置 不依赖于另一个。但是,如果我们的元素是 成对排序,就像 Hash 的字段值对一样,那么应该 用:

foreach key,value {
    AddElement(key);
    AddElement(value);
    EndSequence();
}

因为 key 和 value 将始终按上述顺序排列,而 单个键值对可以出现在 Redis 哈希中的任何位置。

有序元素列表将通过以下方式实现:

foreach element {
    AddElement(element);
}
EndSequence();

RedisModule_DigestAddLongLong

void RedisModule_DigestAddLongLong(RedisModuleDigest *md, long long ll);

从以下版本可用: 4.0.0

喜欢RedisModule_DigestAddStringBuffer()但需要long long作为输入 在将其添加到摘要之前,它会被转换为 String。

RedisModule_DigestEndSequence

void RedisModule_DigestEndSequence(RedisModuleDigest *md);

从以下版本可用: 4.0.0

请参阅以下文档RedisModule_DigestAddElement().

RedisModule_LoadDataTypeFromStringEncver

void *RedisModule_LoadDataTypeFromStringEncver(const RedisModuleString *str,
                                               const moduleType *mt,
                                               int encver);

从以下版本可用: 7.0.0

在特定编码版本 'encver' 中解码模块数据类型 'mt' 的序列化表示 from string 'str' 并返回新分配的值,如果解码失败,则返回 NULL。

此调用基本上重用了 'rdb_load' 回调模块数据类型 implement 以允许模块任意序列化 / 反序列化 键,类似于 Redis 的 'DUMP' 和 'RESTORE' 命令的实现方式。

模块通常应使用REDISMODULE_OPTIONS_HANDLE_IO_ERRORSflag 和 确保反序列化代码正确检查和处理 IO 错误 (释放已分配的缓冲区并返回 NULL)。

如果未完成此作,Redis 将处理损坏的(或只是截断的)序列化 data 来生成错误消息并终止进程。

RedisModule_LoadDataTypeFromString

void *RedisModule_LoadDataTypeFromString(const RedisModuleString *str,
                                         const moduleType *mt);

从以下版本可用: 6.0.0

RedisModule_LoadDataTypeFromStringEncver,保留 API 的原始版本 以实现向后兼容性。

RedisModule_SaveDataTypeToString

RedisModuleString *RedisModule_SaveDataTypeToString(RedisModuleCtx *ctx,
                                                    void *data,
                                                    const moduleType *mt);

从以下版本可用: 6.0.0

将模块数据类型 'mt' 值 'data' 编码为序列化形式,并返回它 作为新分配的RedisModuleString.

此调用基本上重用了 'rdb_save' 回调模块数据类型 implement 以允许模块任意序列化 / 反序列化 键,类似于 Redis 的 'DUMP' 和 'RESTORE' 命令的实现方式。

RedisModule_GetKeyNameFromDigest

const RedisModuleString *RedisModule_GetKeyNameFromDigest(RedisModuleDigest *dig);

从以下版本可用: 7.0.0

返回当前正在处理的键的名称。

RedisModule_GetDbIdFromDigest

int RedisModule_GetDbIdFromDigest(RedisModuleDigest *dig);

从以下版本可用: 7.0.0

返回当前正在处理的密钥的数据库 ID。

模块数据类型的 AOF API

RedisModule_EmitAOF

void RedisModule_EmitAOF(RedisModuleIO *io,
                         const char *cmdname,
                         const char *fmt,
                         ...);

从以下版本可用: 4.0.0

在 AOF 重写过程中向 AOF 发出命令。此功能 仅在aof_rewrite导出的数据类型方法 通过模块。该命令的工作方式与RedisModule_Call()挡路 参数已传递,但它不会返回任何内容作为 Error handling 由 Redis 本身执行。

IO 上下文处理

RedisModule_GetKeyNameFromIO

const RedisModuleString *RedisModule_GetKeyNameFromIO(RedisModuleIO *io);

从以下版本可用: 5.0.5

返回当前正在处理的键的名称。 不能保证键名称始终可用,因此这可能会返回 NULL。

RedisModule_GetKeyNameFromModuleKey

const RedisModuleString *RedisModule_GetKeyNameFromModuleKey(RedisModuleKey *key);

从以下版本可用: 6.0.0

返回一个RedisModuleString将 key 的名称从RedisModuleKey.

RedisModule_GetDbIdFromModuleKey

int RedisModule_GetDbIdFromModuleKey(RedisModuleKey *key);

从以下版本可用: 7.0.0

返回 key 的数据库 ID 来自RedisModuleKey.

RedisModule_GetDbIdFromIO

int RedisModule_GetDbIdFromIO(RedisModuleIO *io);

从以下版本可用: 7.0.0

返回当前正在处理的密钥的数据库 ID。 不能保证此信息始终可用,因此可能会返回 -1。

伐木

RedisModule_Log

void RedisModule_Log(RedisModuleCtx *ctx,
                     const char *levelstr,
                     const char *fmt,
                     ...);

从以下版本可用: 4.0.0

向标准 Redis 日志生成日志消息,格式接受 printf-alike 说明符,而 level 是描述日志的字符串 level 在发出日志时使用,并且必须是以下值之一:

  • “调试” (REDISMODULE_LOGLEVEL_DEBUG)
  • “verbose” (REDISMODULE_LOGLEVEL_VERBOSE)
  • “通知” (REDISMODULE_LOGLEVEL_NOTICE)
  • “警告” (REDISMODULE_LOGLEVEL_WARNING)

如果指定的日志级别无效,则默认使用 verbose。 此功能能够对日志行的长度有固定的限制 要发出,则未指定此限制,但保证大于 几行文字。

如果 ctx 参数无法在 instance线程或回调的调用者,在这种情况下,通用的 “module” 将替换为模块名称。

RedisModule_LogIOError

void RedisModule_LogIOError(RedisModuleIO *io,
                            const char *levelstr,
                            const char *fmt,
                            ...);

从以下版本可用: 4.0.0

记录来自 RDB/AOF 序列化回调的错误。

当回调返回关键的 错误,因为无法加载或保存某些数据 关键原因。

RedisModule__Assert

void RedisModule__Assert(const char *estr, const char *file, int line);

从以下版本可用: 6.0.0

类似 Redis 的 assert 函数。

RedisModule_Assert(expression)是推荐的,而不是 直接调用此函数。

失败的断言将关闭服务器并生成日志记录信息 看起来与 Redis 本身生成的信息相同。

RedisModule_LatencyAddSample

void RedisModule_LatencyAddSample(const char *event, mstime_t latency);

从以下版本可用: 6.0.0

允许将事件添加到延迟监视器中,以便 LATENCY 观察 命令。如果延迟小于配置的 latency-monitor-threshold 的 Latency Monitor-Threshold 中。

阻止客户端访问模块

有关在模块中阻止命令的指南,请参阅 https://redis.io/docs/latest/develop/reference/modules/modules-blocking-ops/

RedisModule_RegisterAuthCallback

void RedisModule_RegisterAuthCallback(RedisModuleCtx *ctx,
                                      RedisModuleAuthCallback cb);

从以下版本可用: 7.2.0

除了基于密码的常规身份验证之外,此 API 还注册了一个要执行的回调。 可以在不同的模块中注册多个回调。当 Module 被卸载时,所有 它注册的 auth 回调将被取消注册。 当 AUTH/HELLO (提供 AUTH 字段)命令。 回调将使用模块上下文以及用户名和密码调用,并且是 预期将执行以下作之一: (1) 身份验证 - 使用RedisModule_AuthenticateClient* API 和返回REDISMODULE_AUTH_HANDLED. 这将立即将身份验证链结束为成功,并添加 OK 回复。 (2) 拒绝身份验证 - 返回REDISMODULE_AUTH_HANDLED而不进行身份验证或阻止 客户。选择err可以设置为自定义错误消息,并且err将自动 由服务器释放。 这将立即将身份验证链结束为不成功,并添加 ERR 回复。 (3) 在身份验证时阻止客户端 - 使用RedisModule_BlockClientOnAuthAPI 和返回REDISMODULE_AUTH_HANDLED.在这里,客户端将被阻止,直到RedisModule_UnblockClient使用 API 这将触发 auth reply 回调(通过RedisModule_BlockClientOnAuth). 在这个回复回调中,Module 应该 authenticate 、 deny 或 skip 处理 authentication 。 (4) 跳过处理 认证 - 返回REDISMODULE_AUTH_NOT_HANDLED而不阻止 客户。这将允许引擎尝试下一个模块 auth 回调。 如果没有任何回调进行身份验证或拒绝身份验证,则尝试基于密码的身份验证,并且 将进行身份验证或添加失败日志,并相应地回复客户端。

注意:如果客户端在阻止模块身份验证时断开连接,则 AUTH 或 HELLO 命令的出现不会在 INFO 命令统计信息中跟踪。

以下是如何使用基于非阻塞模块的身份验证的示例:

 int auth_cb(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) {
     const char *user = RedisModule_StringPtrLen(username, NULL);
     const char *pwd = RedisModule_StringPtrLen(password, NULL);
     if (!strcmp(user,"foo") && !strcmp(pwd,"valid_password")) {
         RedisModule_AuthenticateClientWithACLUser(ctx, "foo", 3, NULL, NULL, NULL);
         return REDISMODULE_AUTH_HANDLED;
     }

     else if (!strcmp(user,"foo") && !strcmp(pwd,"wrong_password")) {
         RedisModuleString *log = RedisModule_CreateString(ctx, "Module Auth", 11);
         RedisModule_ACLAddLogEntryByUserName(ctx, username, log, REDISMODULE_ACL_LOG_AUTH);
         RedisModule_FreeString(ctx, log);
         const char *err_msg = "Auth denied by Misc Module.";
         *err = RedisModule_CreateString(ctx, err_msg, strlen(err_msg));
         return REDISMODULE_AUTH_HANDLED;
     }
     return REDISMODULE_AUTH_NOT_HANDLED;
  }

 int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
     if (RedisModule_Init(ctx,"authmodule",1,REDISMODULE_APIVER_1)== REDISMODULE_ERR)
         return REDISMODULE_ERR;
     RedisModule_RegisterAuthCallback(ctx, auth_cb);
     return REDISMODULE_OK;
 }

RedisModule_BlockClient

RedisModuleBlockedClient *RedisModule_BlockClient(RedisModuleCtx *ctx,
                                                  RedisModuleCmdFunc reply_callback,
                                                  ;

从以下版本可用: 4.0.0

在阻止命令的上下文中阻止客户端,返回句柄 稍后将使用它,以便通过调用RedisModule_UnblockClient().参数指定回调函数 以及超时,在此超时后,客户端将被取消阻止。

在以下上下文中调用回调:

reply_callback:   called after a successful RedisModule_UnblockClient()
                  call in order to reply to the client and unblock it.

timeout_callback: called when the timeout is reached or if `CLIENT UNBLOCK`
                  is invoked, in order to send an error to the client.

free_privdata:    called in order to free the private data that is passed
                  by RedisModule_UnblockClient() call.

注意:RedisModule_UnblockClient应该为每个被阻塞的客户端调用, 即使客户端被杀死、超时或断开连接。未能做到这一点 将导致内存泄漏。

在某些情况下RedisModule_BlockClient()不能用于:

  1. 如果客户端是 Lua 脚本。
  2. 如果客户端正在执行 MULTI 块。

在这些情况下,对RedisModule_BlockClient()不会阻止 client,而是生成特定的错误回复。

一个注册timeout_callback功能也可以解锁 使用CLIENT UNBLOCK命令,这将触发 timeout 回调。 如果未注册回调函数,则被阻止的客户端将 被视为未处于阻塞状态,并且CLIENT UNBLOCK将返回 零值。

测量后台时间:默认情况下,在 blocked 命令中花费的时间 不计入总命令持续时间。要包括这样的时间,您应该 用RedisModule_BlockedClientMeasureTimeStart()RedisModule_BlockedClientMeasureTimeEnd()一 或多次在阻止命令后台工作。

RedisModule_BlockClientOnAuth

RedisModuleBlockedClient *RedisModule_BlockClientOnAuth(RedisModuleCtx *ctx,
                                                        RedisModuleAuthCallback reply_callback,
                                                        ;

从以下版本可用: 7.2.0

阻止当前客户端在后台进行模块身份验证。如果 module auth 不在 progress 时,API 返回 NULL。否则,客户端将被阻止,并且RedisModule_BlockedClient的返回方式类似于RedisModule_BlockClient应用程序接口。 注意:仅在模块 auth 回调的上下文中使用此 API。

RedisModule_BlockClientGetPrivateData

void *RedisModule_BlockClientGetPrivateData(RedisModuleBlockedClient *blocked_client);

从以下版本可用: 7.2.0

获取之前在被阻止的客户端上设置的私有数据

RedisModule_BlockClientSetPrivateData

void RedisModule_BlockClientSetPrivateData(RedisModuleBlockedClient *blocked_client,
                                           void *private_data);

从以下版本可用: 7.2.0

在被阻止的客户端上设置私有数据

RedisModule_BlockClientOnKeys

RedisModuleBlockedClient *RedisModule_BlockClientOnKeys(RedisModuleCtx *ctx,
                                                        RedisModuleCmdFunc reply_callback,
                                                        ;

从以下版本可用: 6.0.0

此调用类似于RedisModule_BlockClient(),但在本例中,我们 不仅要阻止客户端,还要要求 Redis 自动取消阻止 一旦某些键变为 “ready” 状态,即包含更多数据。

基本上,这类似于典型的 Redis 命令通常所做的, 如 BLPOP 或 BZPOPMAX:如果无法尽快提供服务,则客户端会阻止, 稍后,当 key 收到新数据(例如列表推送)时, client 已解除阻止并提供服务。

但是,对于这个模块 API,当客户端被解封时?

  1. 如果阻止具有关联阻塞作的 key 类型,则 就像 List、Sorted Set、Stream 等一样,客户端可以是 取消阻止 取消阻止该类型的本机阻止作。因此,如果我们阻止 在列表键上,RPUSH 命令可能会取消阻止我们的客户端,依此类推。
  2. 如果您正在实现本机数据类型,或者如果要添加新的 解封条件除了 “1” 之外,还可以调用 modules APIRedisModule_SignalKeyAsReady().

无论如何,我们无法确定是否应该仅仅因为 key 被标记为 ready:例如,连续的作可能会更改 key 中,或者在提供此 key 之前在队列中的客户端,修改 key 以及再次将其清空。因此,当客户端被RedisModule_BlockClientOnKeys()Reply 回调在RedisModule_UnblockClient()被调用,但每次键被指示为 ready 时: 如果 reply 回调可以为客户端提供服务,则返回REDISMODULE_OK并且客户端被解封,否则将返回REDISMODULE_ERR我们稍后再试。

reply 回调可以访问由 调用 APIRedisModule_GetBlockedClientReadyKey(),该函数会返回 只需将键的字符串名称作为RedisModuleString对象。

多亏了这个系统,我们可以设置复杂的阻塞场景,例如 仅当列表包含至少 5 个项目或其他 更花哨的逻辑。

请注意,与RedisModule_BlockClient(),是这里 我们在阻塞客户端时直接传递私有数据:它会 稍后在 reply 回调中可访问。通常,当使用RedisModule_BlockClient()要回复客户端的私有数据是 调用RedisModule_UnblockClient()但这里的解锁 都是由 Redis 自己执行的,所以之前我们需要有一些私有数据 手。私有数据用于存储有关特定 unblocking作。此类信息将是 使用free_privdatacallback 回调。

但是,回复回调将能够访问 命令,因此通常不需要私有数据。

注意:一般情况下RedisModule_UnblockClient不应为 为在键上被阻止的客户端调用(键将 准备就绪,否则将发生超时)。如果出于某种原因,您确实希望 调用RedisModule_UnblockClient是可能的:客户端将是 处理(您必须实现超时 callback 调用)。

RedisModule_BlockClientOnKeysWithFlags

RedisModuleBlockedClient *RedisModule_BlockClientOnKeysWithFlags(RedisModuleCtx *ctx,
                                                                 RedisModuleCmdFunc reply_callback,
                                                                 ;

从以下版本可用: 7.2.0

等同RedisModule_BlockClientOnKeys,但可以采用REDISMODULE_BLOCK_*标志 可以是REDISMODULE_BLOCK_UNBLOCK_DEFAULT,这意味着默认行为(相同 作为调用RedisModule_BlockClientOnKeys)

flags 是这些的位掩码:

  • REDISMODULE_BLOCK_UNBLOCK_DELETED:如果出现任何keys将被删除。 对于需要键存在的命令(如 XREADGROUP)最有用

RedisModule_SignalKeyAsReady

void RedisModule_SignalKeyAsReady(RedisModuleCtx *ctx, RedisModuleString *key);

从以下版本可用: 6.0.0

此功能用于潜在地取消阻止被阻止的客户端 on 键与RedisModule_BlockClientOnKeys().调用此函数时, 所有被此密钥阻止的客户端都将获得其reply_callback叫。

RedisModule_UnblockClient

int RedisModule_UnblockClient(RedisModuleBlockedClient *bc, void *privdata);

从以下版本可用: 4.0.0

取消阻止被阻止的客户端RedisModule_BlockedClient.这将触发 为回复客户端而调用的回复回调。 reply 回调可以访问 'privdata' 参数,因此 此函数的调用者可以传递所需的任何值,以便 实际上是回复客户端。

'privdata' 的常见用法是线程计算 需要传递给客户端,包括但不限于一些慢 来计算 reply 或通过网络获取的一些 reply。

注 1:该函数可以从模块生成的线程中调用。

注 2:当我们使用 API 取消阻止被阻止的客户端时RedisModule_BlockClientOnKeys(),则此处不使用 privdata 参数。 使用此 API 取消阻止被阻止的密钥的客户端仍将 要求客户端得到一些回复,因此该函数将使用 “timeout” 处理程序(在RedisModule_BlockClientOnKeys()可从超时访问 回调方式RedisModule_GetBlockedClientPrivateData).

RedisModule_AbortBlock

int RedisModule_AbortBlock(RedisModuleBlockedClient *bc);

从以下版本可用: 4.0.0

Abort a blocked client blocking operation(中止被阻止的客户端阻塞作):客户端将被解除阻塞 而不触发任何回调。

RedisModule_SetDisconnectCallback

void RedisModule_SetDisconnectCallback(RedisModuleBlockedClient *bc,
                                       RedisModuleDisconnectFunc callback);

从以下版本可用: 5.0.0

设置一个回调,当被阻止的客户端断开连接时将调用 在模块有机会调用RedisModule_UnblockClient()

通常,你想要做的是清理你的模块状态 以便您可以调用RedisModule_UnblockClient()安全,否则 如果超时时间较长,则客户端将永远保持阻塞状态。

笔记:

  1. 在这里调用 Reply* 系列函数是不安全的,它也是 因为客户已经走了,所以没用。

  2. 如果客户端因 超时。在这种情况下,客户端会自动解除阻塞 并调用 timeout 回调。

RedisModule_IsBlockedReplyRequest

int RedisModule_IsBlockedReplyRequest(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

如果调用了 module 命令以填充 回复被阻止的客户端。

RedisModule_IsBlockedTimeoutRequest

int RedisModule_IsBlockedTimeoutRequest(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

如果调用了 module 命令以填充 Reply 用于超时的被阻止客户端。

RedisModule_GetBlockedClientPrivateData

void *RedisModule_GetBlockedClientPrivateData(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

通过以下方式获取私有数据集RedisModule_UnblockClient()

RedisModule_GetBlockedClientReadyKey

RedisModuleString *RedisModule_GetBlockedClientReadyKey(RedisModuleCtx *ctx);

从以下版本可用: 6.0.0

获取在上下文中调用 reply 回调时准备好的 key 的客户端被RedisModule_BlockClientOnKeys().

RedisModule_GetBlockedClientHandle

RedisModuleBlockedClient *RedisModule_GetBlockedClientHandle(RedisModuleCtx *ctx);

从以下版本可用: 5.0.0

获取与给定上下文关联的被阻止客户端。 这在被阻止的客户端的回复和超时回调中很有用。 以前,模块有时具有被阻止的客户端句柄引用 周围,并希望清理它。

RedisModule_BlockedClientDisconnected

int RedisModule_BlockedClientDisconnected(RedisModuleCtx *ctx);

从以下版本可用: 5.0.0

如果调用被阻止的客户端的 free 回调,则返回 true, 客户端被解除阻止的原因是它已断开连接 当它被阻止时。

线程安全上下文

RedisModule_GetThreadSafeContext

RedisModuleCtx *RedisModule_GetThreadSafeContext(RedisModuleBlockedClient *bc);

从以下版本可用: 4.0.0

返回一个可以在线程内部使用的上下文,以使 Redis 上下文 调用某些模块 API。如果 'bc' 不是 NULL,则模块将 绑定到被阻止的客户端,并且可以使用RedisModule_Reply*函数系列来累积回复,以便在 客户端将被取消阻止。否则,线程安全上下文将为 由特定客户端分离。

要调用非回复 API,线程安全上下文必须准备好:

RedisModule_ThreadSafeContextLock(ctx);
... make your call here ...
RedisModule_ThreadSafeContextUnlock(ctx);

使用RedisModule_Reply*函数,假设 在创建上下文时使用 blocked 的客户端,否则 不RedisModule_Reply* 应该打电话。

注意:如果要创建分离线程安全上下文(bc 为 NULL), 考虑使用RedisModule_GetDetachedThreadSafeContext这也将保留 模块 ID,因此对日志记录更有用。

RedisModule_GetDetachedThreadSafeContext

RedisModuleCtx *RedisModule_GetDetachedThreadSafeContext(RedisModuleCtx *ctx);

从以下版本可用: 6.0.9

返回一个未与任何 specific blocked 客户端,但与模块的上下文相关联。

这对于希望在 长期,用于日志记录等目的。

RedisModule_FreeThreadSafeContext

void RedisModule_FreeThreadSafeContext(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

释放线程安全上下文。

RedisModule_ThreadSafeContextLock

void RedisModule_ThreadSafeContextLock(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

在执行线程安全 API 调用之前获取服务器锁。 这不是必需的RedisModule_Reply*当有 连接到 Thread Safe 上下文的 blocked 客户端。

RedisModule_ThreadSafeContextTryLock

int RedisModule_ThreadSafeContextTryLock(RedisModuleCtx *ctx);

从以下版本可用: 6.0.8

RedisModule_ThreadSafeContextLock但是这个函数 如果已获取服务器锁,则不会阻止。

如果成功(已获得锁)REDISMODULE_OK返回 否则REDISMODULE_ERR返回 errno 并设置 因此。

RedisModule_ThreadSafeContextUnlock

void RedisModule_ThreadSafeContextUnlock(RedisModuleCtx *ctx);

从以下版本可用: 4.0.0

在执行线程安全 API 调用后释放服务器锁。

模块密钥空间通知 API

RedisModule_SubscribeToKeyspaceEvents

int RedisModule_SubscribeToKeyspaceEvents(RedisModuleCtx *ctx,
                                          int types,
                                          RedisModuleNotificationFunc callback);

从以下版本可用: 4.0.9

订阅密钥空间通知。这是 keyspace-notifications API 的 API 中。模块可以注册要通知的回调 当 keyspace 事件发生时。

通知事件按其类型(字符串事件、设置事件、 等),并且 subscriber 回调仅接收与特定 事件类型的掩码。

使用 订阅通知时RedisModule_SubscribeToKeyspaceEvents该模块必须提供一个 event type-mask,表示订阅者的事件 感兴趣。这可以是以下任何标志的 OR 掩码:

  • REDISMODULE_NOTIFY_GENERIC:DEL、EXPIRE、RENAME 等通用命令
  • REDISMODULE_NOTIFY_STRING:字符串事件
  • REDISMODULE_NOTIFY_LIST:列出事件
  • REDISMODULE_NOTIFY_SET:设置事件
  • REDISMODULE_NOTIFY_HASH:哈希事件
  • REDISMODULE_NOTIFY_ZSET:排序集事件
  • REDISMODULE_NOTIFY_EXPIRED:过期事件
  • REDISMODULE_NOTIFY_EVICTED:驱逐事件
  • REDISMODULE_NOTIFY_STREAM:流事件
  • REDISMODULE_NOTIFY_MODULE:模块类型事件
  • REDISMODULE_NOTIFY_KEYMISS:键失误事件 请注意,key-miss 事件是唯一的类型 of 事件。 使用 write 命令从内部执行RedisModule_Call 此通知是错误的,因此不鼓励。它会 使触发事件的 read 命令为 复制到 AOF/副本。
  • REDISMODULE_NOTIFY_ALL:所有事件(不包括REDISMODULE_NOTIFY_KEYMISS)
  • REDISMODULE_NOTIFY_LOADED:仅适用于模块的特殊通知, 指示密钥是从 Persistence 加载的。 请注意,当此事件触发时,给定的键 不能保留,使用 RedisModule_CreateStringFromString 相反。

我们不区分 key events 和 keyspace 事件,它是 up 添加到模块中,以根据键筛选执行的作。

订阅者签名为:

int (*RedisModuleNotificationFunc) (RedisModuleCtx *ctx, int type,
                                    const char *event,
                                    RedisModuleString *key);

type是事件类型位,必须与注册时给出的掩码匹配 时间。event string 是正在执行的实际命令,key 是 相关的 Redis 键。

通知回调使用不能 用于向客户端发送任何内容,并且具有事件所在的 DB 编号 作为其选定的 DB 编号发生。

请注意,没有必要在 redis.conf 中为 模块通知工作。

警告:通知回调以同步方式执行, 因此通知回调必须快速,否则会减慢 Redis 的速度。 如果需要执行较长的作,请使用线程来卸载它们。

此外,通知是同步执行的事实意味着 通知代码将在 Redis 逻辑的中间执行 (命令 logic、eviction、expire)。更改 key space,而 logic 跑步是危险的,也是令人沮丧的。为了对关键空间事件做出反应 编写作,请参考RedisModule_AddPostNotificationJob.

有关更多信息,请参阅 https://redis.io/topics/notifications

RedisModule_AddPostNotificationJob

int RedisModule_AddPostNotificationJob(RedisModuleCtx *ctx,
                                       RedisModulePostNotificationJobFunc callback,
                                       void *privdata,
                                       void (*free_privdata)(void*));

从以下版本可用: 7.2.0

在密钥空间通知回调中运行时,执行任何写入都是危险的,强烈建议不要执行任何写入 作(见RedisModule_SubscribeToKeyspaceEvents).为了在此场景中仍执行写入作, Redis 提供RedisModule_AddPostNotificationJob应用程序接口。API 允许注册 Redis 将调用的任务回调 当承诺满足以下条件时:

  1. 执行任何写入作都是安全的。
  2. 该作业将与密钥空间通知一起原子调用。

请注意,一个作业可能会触发键空间通知,从而触发更多作业。 这引发了对进入无限循环的担忧,我们考虑无限循环 作为需要在模块中修复的逻辑错误,尝试防止 通过停止执行来无限循环可能会导致违反功能正确性 因此 Redis 不会尝试保护模块免受无限循环的影响。

'free_pd' 可以是 NULL,在这种情况下不会使用。

返回REDISMODULE_OKon success 和REDISMODULE_ERRif 在从磁盘加载数据(AOF 或 RDB)时调用,或者 如果实例是只读副本。

RedisModule_GetNotifyKeyspaceEvents

int RedisModule_GetNotifyKeyspaceEvents(void);

从以下版本可用: 6.0.0

获取 notify-keyspace-events 的配置位图(可以使用 有关其他筛选RedisModuleNotificationFunc)

RedisModule_NotifyKeyspaceEvent

int RedisModule_NotifyKeyspaceEvent(RedisModuleCtx *ctx,
                                    int type,
                                    const char *event,
                                    RedisModuleString *key);

从以下版本可用: 6.0.0

将 notifyKeyspaceEvent 暴露给模块

模块 集群 API

RedisModule_RegisterClusterMessageReceiver

void RedisModule_RegisterClusterMessageReceiver(RedisModuleCtx *ctx,
                                                uint8_t type,
                                                RedisModuleClusterMessageReceiver callback);

从以下版本可用: 5.0.0

为 'type' 类型的集群消息注册回调接收器。如果有 已经是一个已注册的回调,这将替换回调函数 替换为提供的那个,否则如果回调设置为 NULL 并且 已经是此函数的回调,则回调将未注册 (所以这个 API 调用也用于删除接收器)。

RedisModule_SendClusterMessage

int RedisModule_SendClusterMessage(RedisModuleCtx *ctx,
                                   const char *target_id,
                                   uint8_t type,
                                   const char *msg,
                                   uint32_t len);

从以下版本可用: 5.0.0

如果满足以下条件,则向集群中的所有节点发送消息target为 NULL,否则 在指定的目标处,即REDISMODULE_NODE_ID_LENbytes 节点 ID 的 ID 中,作为 由接收方回调或 nodes 迭代函数返回。

该函数返回REDISMODULE_OK如果消息已成功发送, 否则,如果节点未连接或此类节点 ID 未映射到任何 已知集群节点、REDISMODULE_ERR返回。

RedisModule_GetClusterNodesList

char **RedisModule_GetClusterNodesList(RedisModuleCtx *ctx, size_t *numnodes);

从以下版本可用: 5.0.0

返回一个字符串指针数组,每个字符串指针指向一个集群 node ID 为REDISMODULE_NODE_ID_LEN字节(不含任何 null 术语)。 返回的节点 ID 数量将存储在*numnodes. 但是,如果此函数由未运行 Redis 的模块调用 启用了 Redis Cluster 的实例,则返回 NULL。

返回的 ID 可以与RedisModule_GetClusterNodeInfo()挨次 以获取有关单节点的更多信息。

此函数返回的数组必须使用函数释放RedisModule_FreeClusterNodesList().

例:

size_t count, j;
char **ids = RedisModule_GetClusterNodesList(ctx,&count);
for (j = 0; j < count; j++) {
    RedisModule_Log(ctx,"notice","Node %.*s",
        REDISMODULE_NODE_ID_LEN,ids[j]);
}
RedisModule_FreeClusterNodesList(ids);

RedisModule_FreeClusterNodesList

void RedisModule_FreeClusterNodesList(char **ids);

从以下版本可用: 5.0.0

释放使用RedisModule_GetClusterNodesList.

RedisModule_GetMyClusterID

const char *RedisModule_GetMyClusterID(void);

从以下版本可用: 5.0.0

返回此节点 ID (REDISMODULE_CLUSTER_ID_LEN字节)或 NULL (如果集群 已禁用。

RedisModule_GetClusterSize

size_t RedisModule_GetClusterSize(void);

从以下版本可用: 5.0.0

返回集群中的节点数,无论其状态如何 (握手、无地址、......因此活动节点的数量实际上可能 更小,但不能大于此数字。如果实例不在 cluster 模式,则返回 0。

RedisModule_GetClusterNodeInfo

int RedisModule_GetClusterNodeInfo(RedisModuleCtx *ctx,
                                   const char *id,
                                   char *ip,
                                   char *master_id,
                                   int *port,
                                   int *flags);

从以下版本可用: 5.0.0

填充 ID 为指定 'id' 的节点的指定信息, 然后返回REDISMODULE_OK.否则,如果节点 ID 的格式无效 或者此本地节点的 POV 中不存在节点 ID,REDISMODULE_ERR返回。

参数ip,master_id,portflags如果我们不这样做,则可以为 NULL 需要填充回某些信息。如果ipmaster_id(仅填充 如果实例是从属实例),则它们指向持有 至少REDISMODULE_NODE_ID_LEN字节。字符串写回为ipmaster_id不以 null 结尾。

报告的标志列表如下:

  • REDISMODULE_NODE_MYSELF:此节点
  • REDISMODULE_NODE_MASTER:节点是主节点
  • REDISMODULE_NODE_SLAVE:节点是副本
  • REDISMODULE_NODE_PFAIL:我们看到节点失败
  • REDISMODULE_NODE_FAIL:集群同意节点出现故障
  • REDISMODULE_NODE_NOFAILOVER:从站配置为永不故障转移

RedisModule_SetClusterFlags

void RedisModule_SetClusterFlags(RedisModuleCtx *ctx, uint64_t flags);

从以下版本可用: 5.0.0

设置 Redis Cluster 标志以更改 Redis 集群,尤其是以禁用某些功能为目标。 这对于使用 Cluster API 的模块非常有用,以便创建 不同的分布式系统,但仍希望使用 Redis 集群 消息总线。可以设置的标志:

  • CLUSTER_MODULE_FLAG_NO_FAILOVER
  • CLUSTER_MODULE_FLAG_NO_REDIRECTION

具有以下效果:

  • NO_FAILOVER:防止 Redis Cluster 从服务器对死主服务器进行故障转移。 此外,还会禁用副本迁移功能。

  • NO_REDIRECTION:每个节点都将接受任何键,而不会尝试执行 根据 Redis Cluster 算法进行分区。 槽信息仍将在 集群,但没有效果。

RedisModule_ClusterKeySlot

unsigned int RedisModule_ClusterKeySlot(RedisModuleString *key);

从以下版本可用: 7.4.0

返回 key 的 cluster slot,类似于CLUSTER KEYSLOT命令。 即使未启用集群模式,此功能也有效。

RedisModule_ClusterCanonicalKeyNameInSlot

const char *RedisModule_ClusterCanonicalKeyNameInSlot(unsigned int slot);

从以下版本可用: 7.4.0

返回一个短字符串,该字符串可用作键或键中的哈希标签, 这样,键就映射到给定的 cluster 槽。如果 slot 不是,则返回 NULL 一个有效的槽。

模块 计时器 API

模块定时器是一种高精度的 “绿色定时器” 抽象,其中 每个模块都可以毫无问题地注册数百万个计时器,即使 实际的事件循环将只有一个计时器,用于唤醒 module timers 子系统来处理下一个事件。

所有计时器都存储在一个基数树中,按过期时间排序,当 主 Redis 事件循环定时器回调调用后,我们尝试处理所有 计时器已经一个接一个地过期。然后我们重新进入事件 循环注册一个计时器,该计时器将在下一个 to process 模块时过期 计时器将过期。

每次活动计时器列表降至零时,我们都会取消注册 主事件循环计时器,因此当此类功能为 未使用。

RedisModule_CreateTimer

RedisModuleTimerID RedisModule_CreateTimer(RedisModuleCtx *ctx,
                                           mstime_t period,
                                           RedisModuleTimerProc callback,
                                           void *data);

从以下版本可用: 5.0.0

创建一个新的计时器,该计时器将在period毫秒,并将调用 使用dataas 参数。返回的计时器 ID 可以是 用于从计时器获取信息或在计时器触发之前停止它。 请注意,对于重复计时器的常见使用案例(重新注册 的计时器中RedisModuleTimerProccallback)在 此 API 调用: 如果在 'callback' 的开头调用,则表示 该事件将在每个 'period' 触发。 如果在 'callback' 的末尾调用它,则意味着 事件之间会有 'period' 毫秒的间隔。 (如果执行 'callback' 所需的时间可以忽略不计,则两者 以上陈述的含义相同)

RedisModule_StopTimer

int RedisModule_StopTimer(RedisModuleCtx *ctx,
                          RedisModuleTimerID id,
                          void **data);

从以下版本可用: 5.0.0

停止计时器,返回REDISMODULE_OK如果找到计时器,则属于 调用 模块,否则已停止REDISMODULE_ERR返回。 如果不是 NULL,则 data 指针设置为 data 参数的值,当 计时器已创建。

RedisModule_GetTimerInfo

int RedisModule_GetTimerInfo(RedisModuleCtx *ctx,
                             RedisModuleTimerID id,
                             uint64_t *remaining,
                             void **data);

从以下版本可用: 5.0.0

获取有关计时器的信息:触发前的剩余时间 (以毫秒为单位)以及与计时器关联的私有数据指针。 如果指定的计时器不存在或属于其他模块 不返回任何信息,函数返回REDISMODULE_ERR否则REDISMODULE_OK返回。如果满足以下条件,则参数 remaining 或 data 可以为 NULL 调用方不需要某些信息。

模块 EventLoop API

RedisModule_EventLoopAdd

int RedisModule_EventLoopAdd(int fd,
                             int mask,
                             RedisModuleEventLoopFunc func,
                             void *user_data);

从以下版本可用: 7.0.0

将 pipe / socket 事件添加到事件循环中。

  • mask必须是以下值之一:

    • REDISMODULE_EVENTLOOP_READABLE
    • REDISMODULE_EVENTLOOP_WRITABLE
    • REDISMODULE_EVENTLOOP_READABLE | REDISMODULE_EVENTLOOP_WRITABLE

成功时REDISMODULE_OK返回,否则REDISMODULE_ERR,并且 errno 设置为以下值:

  • ERANGE:fd为负数或高于maxclientsRedis 配置。
  • EINVAL:callback为 NULL 或mask值无效。

errno如果出现内部错误,可能会采用其他值。

例:

void onReadable(int fd, void *user_data, int mask) {
    char buf[32];
    int bytes = read(fd,buf,sizeof(buf));
    printf("Read %d bytes \n", bytes);
}
RedisModule_EventLoopAdd(fd, REDISMODULE_EVENTLOOP_READABLE, onReadable, NULL);

RedisModule_EventLoopDel

int RedisModule_EventLoopDel(int fd, int mask);

从以下版本可用: 7.0.0

从事件循环中删除管道/套接字事件。

  • mask必须是以下值之一:

    • REDISMODULE_EVENTLOOP_READABLE
    • REDISMODULE_EVENTLOOP_WRITABLE
    • REDISMODULE_EVENTLOOP_READABLE | REDISMODULE_EVENTLOOP_WRITABLE

成功时REDISMODULE_OK返回,否则REDISMODULE_ERR,并且 errno 设置为以下值:

  • ERANGE:fd为负数或高于maxclientsRedis 配置。
  • EINVAL:mask值无效。

RedisModule_EventLoopAddOneShot

int RedisModule_EventLoopAddOneShot(RedisModuleEventLoopOneShotFunc func,
                                    void *user_data);

从以下版本可用: 7.0.0

可以从其他线程调用此函数,以在 Redis 上触发回调 主线程。成功时REDISMODULE_OK返回。如果func为 NULLREDISMODULE_ERR,并且 errno 设置为 EINVAL。

模块 ACL API

在 Redis 中的身份验证和授权中实现一个钩子。

RedisModule_CreateModuleUser

RedisModuleUser *RedisModule_CreateModuleUser(const char *name);

从以下版本可用: 6.0.0

创建一个 Redis ACL 用户,模块可以使用该用户对客户端进行身份验证。 获取用户后,模块应该设置该用户可以做什么 使用RedisModule_SetUserACL()功能。配置完成后,用户 可用于验证连接,并使用指定的 ACL 规则,使用RedisModule_AuthClientWithUser()功能。

请注意:

  • ACL 命令不会列出在此处创建的用户。
  • 不会检查在此处创建的用户是否具有重复的名称,因此这取决于 调用此函数的模块负责不创建用户 替换为相同的名称。
  • 创建的用户可用于对多个 Redis 连接进行身份验证。

调用方稍后可以使用该函数释放用户RedisModule_FreeModuleUser().调用此函数时,如果存在 仍使用该用户进行身份验证的客户端,它们已断开连接。 释放用户的函数只应在调用者真正 希望使用户无效,以定义具有不同 能力。

RedisModule_FreeModuleUser

int RedisModule_FreeModuleUser(RedisModuleUser *user);

从以下版本可用: 6.0.0

释放给定用户并断开所有已 使用 它进行身份验证。看RedisModule_CreateModuleUser了解详细用法。

RedisModule_SetModuleUserACL

int RedisModule_SetModuleUserACL(RedisModuleUser *user, const char* acl);

从以下版本可用: 6.0.0

设置通过 redis 模块创建的用户的权限 接口。语法与 ACL SETUSER 相同,因此请参阅 acl.c 中的文档以了解更多信息。看RedisModule_CreateModuleUser了解详细用法。

返回REDISMODULE_OKon success 和REDISMODULE_ERR失败时 并将设置一个 errno 来描述作失败的原因。

RedisModule_SetModuleUserACLString

int RedisModule_SetModuleUserACLString(RedisModuleCtx *ctx,
                                       RedisModuleUser *user,
                                       const char *acl,
                                       RedisModuleString **error);

从以下版本可用: 7.0.6

设置具有完整 ACL 字符串(如 1 将在 redis ACL 上使用 SETUSER 命令行 API。这与RedisModule_SetModuleUserACL,一次只执行单个 ACL作。

返回REDISMODULE_OKon success 和REDISMODULE_ERR失败时 如果RedisModuleString在 error 中提供,则描述错误的字符串 将返回

RedisModule_GetModuleUserACLString

RedisModuleString *RedisModule_GetModuleUserACLString(RedisModuleUser *user);

从以下版本可用: 7.0.6

获取给定用户的 ACL 字符串 返回一个RedisModuleString

RedisModule_GetCurrentUserName

RedisModuleString *RedisModule_GetCurrentUserName(RedisModuleCtx *ctx);

从以下版本可用: 7.0.0

检索当前上下文后面的客户端连接的用户名。 用户名可以稍后使用,以便获取RedisModuleUser. 有关更多信息,请参阅RedisModule_GetModuleUserFromUserName.

返回的字符串必须使用RedisModule_FreeString()或通过 启用自动内存管理。

RedisModule_GetModuleUserFromUserName

RedisModuleUser *RedisModule_GetModuleUserFromUserName(RedisModuleString *name);

从以下版本可用: 7.0.0

一个RedisModuleUser可用于检查是否可以执行命令、键或通道或 根据与该用户关联的 ACL 规则进行访问。 当模块想要对通用 ACL 用户(不是由RedisModule_CreateModuleUser), 它可以获取RedisModuleUser从此 API 中,根据 检索到RedisModule_GetCurrentUserName.

由于可以随时删除通用 ACL 用户,因此此RedisModuleUser应仅在上下文中使用 调用此函数的位置。为了在该上下文中执行 ACL 检查,Module 可以存储用户名 并在任何其他上下文中调用此 API。

如果用户被禁用或用户不存在,则返回 NULL。 调用方应稍后使用函数释放用户RedisModule_FreeModuleUser().

RedisModule_ACLCheckCommandPermissions

int RedisModule_ACLCheckCommandPermissions(RedisModuleUser *user,
                                           RedisModuleString **argv,
                                           int argc);

从以下版本可用: 7.0.0

根据与之关联的 ACL 检查用户是否可以执行该命令。

成功时REDISMODULE_OK返回,否则REDISMODULE_ERR,并且 errno 设置为以下值:

  • ENOENT:指定的命令不存在。
  • EACCES:根据 ACL 规则,无法执行命令

RedisModule_ACLCheckKeyPermissions

int RedisModule_ACLCheckKeyPermissions(RedisModuleUser *user,
                                       RedisModuleString *key,
                                       int flags);

从以下版本可用: 7.0.0

根据用户附加的 ACL 检查用户是否可以访问 Key 以及表示密钥访问的标志。这些标志与 keyspec 进行逻辑作。这些标志记录在RedisModule_SetCommandInfo如 这REDISMODULE_CMD_KEY_ACCESS,REDISMODULE_CMD_KEY_UPDATE,REDISMODULE_CMD_KEY_INSERT, 和REDISMODULE_CMD_KEY_DELETE标志。

如果未提供标志,则用户仍需要对 此命令成功返回。

如果用户能够访问密钥,则REDISMODULE_OK返回,否则REDISMODULE_ERR,并且 errno 设置为以下值之一:

  • EINVAL:提供的标志无效。
  • EACCESS:用户没有访问密钥的权限。

RedisModule_ACLCheckChannelPermissions

int RedisModule_ACLCheckChannelPermissions(RedisModuleUser *user,
                                           RedisModuleString *ch,
                                           int flags);

从以下版本可用: 7.0.0

检查用户是否可以根据给定的 pubsub 频道访问 访问标志。看RedisModule_ChannelAtPosWithFlags有关 可以传入的标志。

如果用户能够访问 pubsub 频道,则REDISMODULE_OK返回,否则REDISMODULE_ERR,并且 errno 设置为以下值之一:

  • EINVAL:提供的标志无效。
  • EACCESS:用户没有访问 pubsub 频道的权限。

RedisModule_ACLAddLogEntry

int RedisModule_ACLAddLogEntry(RedisModuleCtx *ctx,
                               RedisModuleUser *user,
                               RedisModuleString *object,
                               RedisModuleACLLogEntryReason reason);

从以下版本可用: 7.0.0

在 ACL 日志中添加新条目。 返回REDISMODULE_OKon success 和REDISMODULE_ERR出错时。

有关 ACL 日志的更多信息,请参考 https://redis.io/commands/acl-log

RedisModule_ACLAddLogEntryByUserName

int RedisModule_ACLAddLogEntryByUserName(RedisModuleCtx *ctx,
                                         RedisModuleString *username,
                                         RedisModuleString *object,
                                         RedisModuleACLLogEntryReason reason);

从以下版本可用: 7.2.0

在 ACL 日志中添加一个新条目,其中包含username RedisModuleString提供。 返回REDISMODULE_OKon success 和REDISMODULE_ERR出错时。

有关 ACL 日志的更多信息,请参考 https://redis.io/commands/acl-log

RedisModule_AuthenticateClientWithUser

int RedisModule_AuthenticateClientWithUser(RedisModuleCtx *ctx,
                                           RedisModuleUser *module_user,
                                           RedisModuleUserChangedFunc callback,
                                           void *privdata,
                                           uint64_t *client_id);

从以下版本可用: 6.0.0

使用提供的 redis acl 用户对当前上下文的用户进行身份验证。 返回REDISMODULE_ERR如果用户被禁用。

有关回调的信息,请参阅 authenticateClientWithUser,client_id, 以及身份验证的一般用法。

RedisModule_AuthenticateClientWithACLUser

int RedisModule_AuthenticateClientWithACLUser(RedisModuleCtx *ctx,
                                              const char *name,
                                              size_t len,
                                              RedisModuleUserChangedFunc callback,
                                              void *privdata,
                                              uint64_t *client_id);

从以下版本可用: 6.0.0

使用提供的 redis acl 用户对当前上下文的用户进行身份验证。 返回REDISMODULE_ERR如果用户被禁用或用户不存在。

有关回调的信息,请参阅 authenticateClientWithUser,client_id, 以及身份验证的一般用法。

RedisModule_DeauthenticateAndCloseClient

int RedisModule_DeauthenticateAndCloseClient(RedisModuleCtx *ctx,
                                             uint64_t client_id);

从以下版本可用: 6.0.0

取消身份验证并关闭客户端。客户端资源不会是 立即释放,但将在后台作业中清理。这是 取消对客户端进行身份验证的推荐方法,因为大多数客户端无法 处理用户被取消身份验证。返回REDISMODULE_ERR当 client 不存在,并且REDISMODULE_OK当作成功时。

客户端 ID 从RedisModule_AuthenticateClientWithUserRedisModule_AuthenticateClientWithACLUserAPI,但可以通过 CLIENT API 或通过服务器事件。

此函数不是线程安全的,必须在上下文中执行 命令或线程安全上下文。

RedisModule_RedactClientCommandArgument

int RedisModule_RedactClientCommandArgument(RedisModuleCtx *ctx, int pos);

从以下版本可用: 7.0.0

编辑在给定位置指定的客户端命令参数。已编辑的参数 在面向用户的命令(如 SLOWLOG 或 MONITOR)以及 永远不会写入服务器日志。此命令可以在 相同的位置。

请注意,命令名称 position 0 不能被编辑。

返回REDISMODULE_OK如果参数被编辑,并且REDISMODULE_ERR如果有 是传入的无效参数或位置在客户端之外 参数范围。

RedisModule_GetClientCertificate

RedisModuleString *RedisModule_GetClientCertificate(RedisModuleCtx *ctx,
                                                    uint64_t client_id);

从以下版本可用: 6.0.9

返回客户端用于身份验证的 X.509 客户端证书 这个连接。

返回值是已分配的RedisModuleString即 X.509 证书 以 PEM (Base64) 格式编码。它应该由调用方释放 (或自动释放) 。

在以下情况下,将返回 NULL 值:

  • 连接 ID 不存在
  • 连接不是 TLS 连接
  • 连接是 TLS 连接,但未使用客户端证书

模块字典 API

实现一个排序字典(实际上由基数树支持),使用 通常的 get / set / del / num-items API 以及一个迭代器 能够来回切换。

RedisModule_CreateDict

RedisModuleDict *RedisModule_CreateDict(RedisModuleCtx *ctx);

从以下版本可用: 5.0.0

创建新词典。'ctx' 指针可以是当前模块上下文 或 NULL,具体取决于所需内容。请遵守以下规则:

  1. 如果计划保留对此字典的引用,请使用 NULL 上下文 这将在您创建它的 Module 回调后继续存在。
  2. 如果在创建时没有可用的上下文,请使用 NULL 上下文 字典(当然......
  3. 但是,如果 字典 Time to Live 仅限于回调范围。在这个 的情况下,如果启用,您可以享受自动内存管理,这将 回收字典内存,以及 Next / Prev 字典迭代器调用。

RedisModule_FreeDict

void RedisModule_FreeDict(RedisModuleCtx *ctx, RedisModuleDict *d);

从以下版本可用: 5.0.0

释放使用 创建的词典RedisModule_CreateDict().您需要将 上下文指针 'ctx' (如果字典是使用 context 而不是传递 NULL。

RedisModule_DictSize

uint64_t RedisModule_DictSize(RedisModuleDict *d);

从以下版本可用: 5.0.0

返回字典的大小 (键数)。

RedisModule_DictSetC

int RedisModule_DictSetC(RedisModuleDict *d,
                         void *key,
                         size_t keylen,
                         void *ptr);

从以下版本可用: 5.0.0

将指定的 key 存储到字典中,将其值设置为 指针 'ptr' 的如果密钥添加成功,则因为它没有 已经存在,REDISMODULE_OK返回。否则,如果密钥已经 exists 函数返回REDISMODULE_ERR.

RedisModule_DictReplaceC

int RedisModule_DictReplaceC(RedisModuleDict *d,
                             void *key,
                             size_t keylen,
                             void *ptr);

从以下版本可用: 5.0.0

喜欢RedisModule_DictSetC()但会将 key 替换为新的 值(如果键已存在)。

RedisModule_DictSet

int RedisModule_DictSet(RedisModuleDict *d, RedisModuleString *key, void *ptr);

从以下版本可用: 5.0.0

喜欢RedisModule_DictSetC()但将 key 作为RedisModuleString.

RedisModule_DictReplace

int RedisModule_DictReplace(RedisModuleDict *d,
                            RedisModuleString *key,
                            void *ptr);

从以下版本可用: 5.0.0

喜欢RedisModule_DictReplaceC()但将 key 作为RedisModuleString.

RedisModule_DictGetC

void *RedisModule_DictGetC(RedisModuleDict *d,
                           void *key,
                           size_t keylen,
                           int *nokey);

从以下版本可用: 5.0.0

返回存储在指定 key 中的值。该函数返回 NULL 在密钥不存在的情况下,或者如果您实际存储了 在键处为 NULL。因此,如果 'nokey' 指针不是 NULL,则可选地将 如果键不存在,则通过 reference 设置为 1,如果键不存在,则设置为 0 存在。

RedisModule_DictGet

void *RedisModule_DictGet(RedisModuleDict *d,
                          RedisModuleString *key,
                          int *nokey);

从以下版本可用: 5.0.0

喜欢RedisModule_DictGetC()但将 key 作为RedisModuleString.

RedisModule_DictDelC

int RedisModule_DictDelC(RedisModuleDict *d,
                         void *key,
                         size_t keylen,
                         void *oldval);

从以下版本可用: 5.0.0

从字典中删除指定的键,返回REDISMODULE_OK如果 找到并删除了密钥,或者REDISMODULE_ERR如果 字典中没有这样的键。作成功后,如果 'oldval' 不是 NULL,则 '*oldval' 被设置为存储在 键。使用此功能,可以获得 指向值的指针(例如,为了释放它),没有 不得不调用RedisModule_DictGet()在删除密钥之前。

RedisModule_DictDel

int RedisModule_DictDel(RedisModuleDict *d,
                        RedisModuleString *key,
                        void *oldval);

从以下版本可用: 5.0.0

喜欢RedisModule_DictDelC()但将 Key 作为RedisModuleString.

RedisModule_DictIteratorStartC

RedisModuleDictIter *RedisModule_DictIteratorStartC(RedisModuleDict *d,
                                                    const char *op,
                                                    void *key,
                                                    size_t keylen);

从以下版本可用: 5.0.0

返回一个迭代器,setup 以便从指定的 key 通过应用运算符 'op' 来调用,该运算符只是一个字符串,指定 comparison 运算符来查找第一个元素。这 可用的运算符包括:

  • ^– 寻找第一个(按字典顺序排列较小的)键。
  • $– 寻找最后一个(按字典顺序排列更大)的键。
  • >\u2012 查找大于指定键的第一个元素。
  • >=\u2012 查找大于或等于指定键的第一个元素。
  • <– 查找小于指定键的第一个元素。
  • <=– 查找小于或等于指定键的第一个元素。
  • ==\u2012 查找与指定键完全匹配的第一个元素。

请注意,for 和传递的 key 不会被使用,用户可以 只需传递长度为 0 的 NULL 即可。^$

如果无法根据 key 和 operator 传递,RedisModule_DictNext()/ Prev() 只会返回REDISMODULE_ERR在第一次调用时,否则它们将生成 elements。

RedisModule_DictIteratorStart

RedisModuleDictIter *RedisModule_DictIteratorStart(RedisModuleDict *d,
                                                   const char *op,
                                                   RedisModuleString *key);

从以下版本可用: 5.0.0

完全一样RedisModule_DictIteratorStartC,但该键作为RedisModuleString.

RedisModule_DictIteratorStop

void RedisModule_DictIteratorStop(RedisModuleDictIter *di);

从以下版本可用: 5.0.0

释放使用RedisModule_DictIteratorStart().此调用 是强制性的,否则会在模块中引入内存泄漏。

RedisModule_DictIteratorReseekC

int RedisModule_DictIteratorReseekC(RedisModuleDictIter *di,
                                    const char *op,
                                    void *key,
                                    size_t keylen);

从以下版本可用: 5.0.0

创建后RedisModule_DictIteratorStart(),则可以 使用此 API 调用。基于 operator 和 key 的结果与 函数RedisModule_DictIteratorStart(),但在本例中, 返回值只是REDISMODULE_OK如果找到 seeked 元素, 或REDISMODULE_ERR如果无法查找指定的 元素。可以根据需要多次重新搜索迭代器。

RedisModule_DictIteratorReseek

int RedisModule_DictIteratorReseek(RedisModuleDictIter *di,
                                   const char *op,
                                   RedisModuleString *key);

从以下版本可用: 5.0.0

喜欢RedisModule_DictIteratorReseekC()但将 key 作为RedisModuleString.

RedisModule_DictNextC

void *RedisModule_DictNextC(RedisModuleDictIter *di,
                            size_t *keylen,
                            void **dataptr);

从以下版本可用: 5.0.0

返回字典迭代器的当前项di并逐步执行 next 元素。如果迭代器已经生成最后一个元素,并且 没有其他元素返回,则返回 NULL,否则返回指针 设置为表示键的字符串,并且*keylen长度 由引用设置(如果 keylen 不为 NULL)。这*dataptr,如果不是 NULL 设置为存储在返回键处的指针的值作为 auxiliary data(由RedisModule_DictSetAPI) 的 API 进行。

使用示例:

 ... create the iterator here ...
 char *key;
 void *data;
 while((key = RedisModule_DictNextC(iter,&keylen,&data)) != NULL) {
     printf("%.*s %p\n", (int)keylen, key, data);
 }

返回的指针是 void 类型,因为有时它是有意义的 将其转换为char*有时更改为 unsignedchar*取决于 事实上它包含或不包含二进制数据,因此此 API 最终会更多 使用舒适。

返回的指针的有效期一直持续到下次调用 next/prev 迭代器步骤。此外,一旦 iterator 被释放。

RedisModule_DictPrevC

void *RedisModule_DictPrevC(RedisModuleDictIter *di,
                            size_t *keylen,
                            void **dataptr);

从以下版本可用: 5.0.0

这个函数跟RedisModule_DictNext()但是在返回 当前选定的元素,它会选择上一个 元素(按字典顺序更小)而不是下一个。

RedisModule_DictNext

RedisModuleString *RedisModule_DictNext(RedisModuleCtx *ctx,
                                        RedisModuleDictIter *di,
                                        void **dataptr);

从以下版本可用: 5.0.0

喜欢RedisModuleNextC(),而不是返回内部分配的 buffer 和 key length 时,它直接返回分配的模块字符串对象 在指定的上下文 'ctx' 中(它可能为 NULL,与 main 完全相同 应用程序接口RedisModule_CreateString).

返回的字符串对象应在使用后手动释放 或者使用激活了 Automatic Memory Management 的上下文。

RedisModule_DictPrev

RedisModuleString *RedisModule_DictPrev(RedisModuleCtx *ctx,
                                        RedisModuleDictIter *di,
                                        void **dataptr);

从以下版本可用: 5.0.0

喜欢RedisModule_DictNext()但是在返回当前选中的 元素中,它会选择前一个元素(按字典顺序 smaller) 而不是下一个。

RedisModule_DictCompareC

int RedisModule_DictCompareC(RedisModuleDictIter *di,
                             const char *op,
                             void *key,
                             size_t keylen);

从以下版本可用: 5.0.0

将迭代器当前指向的元素与指定的 元素,根据运算符 'op' ( valid 运算符相同,对RedisModule_DictIteratorStart). 如果比较成功,则命令返回REDISMODULE_OK否则REDISMODULE_ERR返回。

当我们只想发出字典范围时,这很有用,因此 在循环中,当我们迭代元素时,我们还可以检查我们是否仍然 在范围内。

函数返回REDISMODULE_ERR如果迭代器到达 End of Elements 条件。

RedisModule_DictCompare

int RedisModule_DictCompare(RedisModuleDictIter *di,
                            const char *op,
                            RedisModuleString *key);

从以下版本可用: 5.0.0

喜欢RedisModule_DictCompareC但获取 key 以与当前 iterator 键作为RedisModuleString.

Modules Info 字段

RedisModule_InfoAddSection

int RedisModule_InfoAddSection(RedisModuleInfoCtx *ctx, const char *name);

从以下版本可用: 6.0.0

用于在添加任何字段之前开始新部分。部分名称将 前缀为<modulename>_并且必须仅包含 A-Z,a-z,0-9。 NULL 或空字符串表示默认部分(仅<modulename>) 被使用。 当返回值为REDISMODULE_ERR,该部分应该而且将要跳过。

RedisModule_InfoBeginDictField

int RedisModule_InfoBeginDictField(RedisModuleInfoCtx *ctx, const char *name);

从以下版本可用: 6.0.0

启动一个 dict 字段,类似于 INFO KEYSPACE 中的字段。使用正常RedisModule_InfoAddField* 函数将项添加到此字段,以及 终止于RedisModule_InfoEndDictField.

RedisModule_InfoEndDictField

int RedisModule_InfoEndDictField(RedisModuleInfoCtx *ctx);

从以下版本可用: 6.0.0

结束 dict 字段,请参阅RedisModule_InfoBeginDictField

RedisModule_InfoAddFieldString

int RedisModule_InfoAddFieldString(RedisModuleInfoCtx *ctx,
                                   const char *field,
                                   RedisModuleString *value);

从以下版本可用: 6.0.0

使用者RedisModuleInfoFunc以添加信息字段。 每个字段将自动以<modulename>_. 字段名称或值不得包含\r\n:.

RedisModule_InfoAddFieldCString

int RedisModule_InfoAddFieldCString(RedisModuleInfoCtx *ctx,
                                    const char *field,
                                    const char *value);

从以下版本可用: 6.0.0

RedisModule_InfoAddFieldString().

RedisModule_InfoAddFieldDouble

int RedisModule_InfoAddFieldDouble(RedisModuleInfoCtx *ctx,
                                   const char *field,
                                   double value);

从以下版本可用: 6.0.0

RedisModule_InfoAddFieldString().

RedisModule_InfoAddFieldLongLong

int RedisModule_InfoAddFieldLongLong(RedisModuleInfoCtx *ctx,
                                     const char *field,
                                     long long value);

从以下版本可用: 6.0.0

RedisModule_InfoAddFieldString().

RedisModule_InfoAddFieldULongLong

int RedisModule_InfoAddFieldULongLong(RedisModuleInfoCtx *ctx,
                                      const char *field,
                                      unsigned long long value);

从以下版本可用: 6.0.0

RedisModule_InfoAddFieldString().

RedisModule_RegisterInfoFunc

int RedisModule_RegisterInfoFunc(RedisModuleCtx *ctx, RedisModuleInfoFunc cb);

从以下版本可用: 6.0.0

注册 INFO 命令的回调。回调应添加 INFO 字段 通过调用RedisModule_InfoAddField*()功能。

RedisModule_GetServerInfo

RedisModuleServerInfoData *RedisModule_GetServerInfo(RedisModuleCtx *ctx,
                                                     const char *section);

从以下版本可用: 6.0.0

获取有关服务器的信息,类似于从 INFO 命令。此函数采用可选的 'section' 参数,该参数可以 为 NULL。返回值保存输出,可与RedisModule_ServerInfoGetField等获取各个字段。 完成后,需要使用RedisModule_FreeServerInfo或使用 自动内存管理机制(如果启用)。

RedisModule_FreeServerInfo

void RedisModule_FreeServerInfo(RedisModuleCtx *ctx,
                                RedisModuleServerInfoData *data);

从以下版本可用: 6.0.0

使用 创建的免费数据RedisModule_GetServerInfo().您需要将 上下文指针 'ctx' (如果字典是使用 context 而不是传递 NULL。

RedisModule_ServerInfoGetField

RedisModuleString *RedisModule_ServerInfoGetField(RedisModuleCtx *ctx,
                                                  RedisModuleServerInfoData *data,
                                                  const char* field);

从以下版本可用: 6.0.0

从使用RedisModule_GetServerInfo().你 仅当你想使用 auto memory 时才需要传递上下文指针 'ctx' 机制来释放返回的字符串。如果 未找到 field。

RedisModule_ServerInfoGetFieldC

const char *RedisModule_ServerInfoGetFieldC(RedisModuleServerInfoData *data,
                                            const char* field);

从以下版本可用: 6.0.0

RedisModule_ServerInfoGetField,但返回一个 char*,该 char* 不应被释放,而应释放调用方。

RedisModule_ServerInfoGetFieldSigned

long long RedisModule_ServerInfoGetFieldSigned(RedisModuleServerInfoData *data,
                                               const char* field,
                                               int *out_err);

从以下版本可用: 6.0.0

从使用RedisModule_GetServerInfo().如果 field 未找到,或者不是数字或超出范围,则返回值将为 0 和可选的out_err参数将设置为REDISMODULE_ERR.

RedisModule_ServerInfoGetFieldUnsigned

unsigned long long RedisModule_ServerInfoGetFieldUnsigned(RedisModuleServerInfoData *data,
                                                          const char* field,
                                                          int *out_err);

从以下版本可用: 6.0.0

从使用RedisModule_GetServerInfo().如果 field 未找到,或者不是数字或超出范围,则返回值将为 0 和可选的out_err参数将设置为REDISMODULE_ERR.

RedisModule_ServerInfoGetFieldDouble

double RedisModule_ServerInfoGetFieldDouble(RedisModuleServerInfoData *data,
                                            const char* field,
                                            int *out_err);

从以下版本可用: 6.0.0

从使用RedisModule_GetServerInfo().如果 field 未找到,或者不是 double,则返回值将为 0,并且 自选out_err参数将设置为REDISMODULE_ERR.

模块实用程序 API

RedisModule_GetRandomBytes

void RedisModule_GetRandomBytes(unsigned char *dst, size_t len);

从以下版本可用: 5.0.0

在计数器模式下使用 SHA1 和 /dev/urandom 返回随机字节 initialized seed。这个函数速度很快,所以可以用来生成 许多字节,对作系统熵池没有任何影响。 目前,此函数不是线程安全的。

RedisModule_GetRandomHexChars

void RedisModule_GetRandomHexChars(char *dst, size_t len);

从以下版本可用: 5.0.0

喜欢RedisModule_GetRandomBytes()而不是将字符串设置为 random bytes 字符串在 十六进制字符集 [0-9a-f]。

模块 API 导出/导入

RedisModule_ExportSharedAPI

int RedisModule_ExportSharedAPI(RedisModuleCtx *ctx,
                                const char *apiname,
                                void *func);

从以下版本可用: 5.0.4

此函数由模块调用,以便导出一些带有 名。其他模块将能够通过调用 对称函数RedisModule_GetSharedAPI()并将返回值转换为 正确的函数指针。

该函数将返回REDISMODULE_OK如果尚未使用该名称,则 否则REDISMODULE_ERR将返回,并且不会执行任何作 执行。

重要提示:apiname 参数应该是带有 static 的字符串文字 辈子。API 依赖于它始终在 未来。

RedisModule_GetSharedAPI

void *RedisModule_GetSharedAPI(RedisModuleCtx *ctx, const char *apiname);

从以下版本可用: 5.0.4

请求导出的 API 指针。返回值只是一个 void 指针 此函数的调用方将需要向右转换 function 指针,所以这是模块之间的私有契约。

如果请求的 API 不可用,则返回 NULL。因为 模块可以在不同的时间以不同的顺序加载,这 函数调用应该放在一些模块通用 API 注册中 步骤,每次模块尝试执行 命令:如果某些 API 无法解析,则 命令应返回错误。

下面是一个示例:

int ... myCommandImplementation(void) {
   if (getExternalAPIs() == 0) {
        reply with an error here if we cannot have the APIs
   }
   // Use the API:
   myFunctionPointer(foo);
}

函数 registerAPI() 是:

int getExternalAPIs(void) {
    static int api_loaded = 0;
    if (api_loaded != 0) return 1; // APIs already resolved.

    myFunctionPointer = RedisModule_GetSharedAPI("...");
    if (myFunctionPointer == NULL) return 0;

    return 1;
}

模块命令过滤器 API

RedisModule_RegisterCommandFilter

RedisModuleCommandFilter *RedisModule_RegisterCommandFilter(RedisModuleCtx *ctx,
                                                            RedisModuleCommandFilterFunc callback,
                                                            int flags);

从以下版本可用: 5.0.5

注册新的 command filter 函数。

命令过滤使模块可以通过插入来扩展 Redis 添加到所有命令的执行流程中。

在 Redis 执行任何命令之前调用已注册的筛选器。这 包括核心 Redis 命令和由任何模块注册的命令。这 filter 适用于所有执行路径,包括:

  1. 客户端调用。
  2. 调用 方式RedisModule_Call()by any module.
  3. 通过 Lua 调用redis.call().
  4. 从主服务器复制命令。

过滤器在特殊的过滤器上下文中执行,该上下文是不同的,并且更多 限于RedisModuleCtx.由于过滤器会影响任何命令,因此它会 必须以非常有效的方式实施,以减少对性能的影响 在 Redis 上。所有需要有效上下文的 Redis 模块 API 调用(例如RedisModule_Call(),RedisModule_OpenKey()等)在 filter 上下文。

RedisModuleCommandFilterCtx可用于检查或修改 executed 命令及其参数。由于筛选器在 Redis 之前执行 开始处理命令,任何更改都会影响命令的方式 处理。例如,模块可以通过以下方式覆盖 Redis 命令:

  1. 注册一个MODULE.SET命令实现 RedisSET命令。
  2. 注册一个命令过滤器,用于检测SET在特定的 键的模式。一旦检测到,过滤器将替换第一个 argument fromSETMODULE.SET.
  3. 当筛选条件执行完成后,Redis 会考虑新的命令名称 因此执行模块自己的命令。

请注意,在上述用例中,如果MODULE.SET本身使用RedisModule_Call()过滤器也将应用于该调用。如果 ,则REDISMODULE_CMDFILTER_NOSELFflag 可以在 注册过滤器。

REDISMODULE_CMDFILTER_NOSELF标志阻止执行 源自模块自己的RedisModule_Call()无法到达过滤器。这 标志对所有执行流(包括嵌套流)都有效,只要 执行从模块的命令上下文或线程安全的 context 的命令。

分离的线程安全上下文与模块关联,并且不能 受此标志保护。

如果注册了多个过滤器(由相同或不同的模块),则它们 将按注册顺序执行。

RedisModule_UnregisterCommandFilter

int RedisModule_UnregisterCommandFilter(RedisModuleCtx *ctx,
                                        RedisModuleCommandFilter *filter);

从以下版本可用: 5.0.5

取消注册命令过滤器。

RedisModule_CommandFilterArgsCount

int RedisModule_CommandFilterArgsCount(RedisModuleCommandFilterCtx *fctx);

从以下版本可用: 5.0.5

返回筛选命令具有的参数数。的 参数包括命令本身。

RedisModule_CommandFilterArgGet

RedisModuleString *RedisModule_CommandFilterArgGet(RedisModuleCommandFilterCtx *fctx,
                                                   int pos);

从以下版本可用: 5.0.5

返回指定的 command 参数。第一个参数(位置 0)是 命令本身和其余部分是用户提供的 args。

RedisModule_CommandFilterArgInsert

int RedisModule_CommandFilterArgInsert(RedisModuleCommandFilterCtx *fctx,
                                       int pos,
                                       RedisModuleString *arg);

从以下版本可用: 5.0.5

通过在指定的 位置。指定的RedisModuleString参数可由 Redis 使用 在 filter 上下文被销毁后,因此它不能是 auto-memory 分配、释放或在其他位置使用。

RedisModule_CommandFilterArgReplace

int RedisModule_CommandFilterArgReplace(RedisModuleCommandFilterCtx *fctx,
                                        int pos,
                                        RedisModuleString *arg);

从以下版本可用: 5.0.5

通过将现有参数替换为新参数来修改 filtered 命令。 指定的RedisModuleString参数可以被 Redis 在 filter 上下文被销毁,因此它不能被自动分配、释放 或用于其他地方。

RedisModule_CommandFilterArgDelete

int RedisModule_CommandFilterArgDelete(RedisModuleCommandFilterCtx *fctx,
                                       int pos);

从以下版本可用: 5.0.5

通过删除指定 位置。

RedisModule_CommandFilterGetClientId

unsigned long long RedisModule_CommandFilterGetClientId(RedisModuleCommandFilterCtx *fctx);

从以下版本可用: 7.2.0

获取发出我们正在筛选的命令的客户端的客户端 ID

RedisModule_MallocSize

size_t RedisModule_MallocSize(void* ptr);

从以下版本可用: 6.0.0

对于通过RedisModule_Alloc()RedisModule_Realloc(),返回为其分配的内存量。 请注意,这可能与我们分配的内存不同(更大) 使用 allocation 调用,因为有时底层分配器 将分配更多内存。

RedisModule_MallocUsableSize

size_t RedisModule_MallocUsableSize(void *ptr);

从以下版本可用: 7.0.1

RedisModule_MallocSize,区别在于RedisModule_MallocUsableSize返回模块的可用内存大小。

RedisModule_MallocSizeString

size_t RedisModule_MallocSizeString(RedisModuleString* str);

从以下版本可用: 7.0.0

等同RedisModule_MallocSize,但它适用于RedisModuleString指针。

RedisModule_MallocSizeDict

size_t RedisModule_MallocSizeDict(RedisModuleDict* dict);

从以下版本可用: 7.0.0

等同RedisModule_MallocSize,但它适用于RedisModuleDict指针。 请注意,返回的值只是底层结构体的开销, 它不包括键和值的分配大小。

RedisModule_GetUsedMemoryRatio

float RedisModule_GetUsedMemoryRatio(void);

从以下版本可用: 6.0.0

返回 0 到 1 之间的 a 数字,表示内存量 当前使用,相对于 Redis 的 “maxmemory” 配置。

  • 0 - 未配置内存限制。
  • 介于 0 和 1 之间 - 在 0-1 范围内标准化的已用内存百分比。
  • 正好 1 - 达到内存限制。
  • 大于 1 - 使用的内存超过配置的限制。

扫描密钥空间和哈希

RedisModule_ScanCursorCreate

RedisModuleScanCursor *RedisModule_ScanCursorCreate(void);

从以下版本可用: 6.0.0

创建要使用的新游标RedisModule_Scan

RedisModule_ScanCursorRestart

void RedisModule_ScanCursorRestart(RedisModuleScanCursor *cursor);

从以下版本可用: 6.0.0

重新启动现有游标。将重新扫描密钥。

RedisModule_ScanCursorDestroy

void RedisModule_ScanCursorDestroy(RedisModuleScanCursor *cursor);

从以下版本可用: 6.0.0

销毁游标结构。

RedisModule_Scan

int RedisModule_Scan(RedisModuleCtx *ctx,
                     RedisModuleScanCursor *cursor,
                     RedisModuleScanCB fn,
                     void *privdata);

从以下版本可用: 6.0.0

允许模块扫描 所选数据库。

扫描实现的回调。

void scan_callback(RedisModuleCtx *ctx, RedisModuleString *keyname,
                   RedisModuleKey *key, void *privdata);
  • ctx:为扫描提供的 Redis 模块上下文。
  • keyname:由调用方拥有,如果在此之后使用,则需要保留 功能。
  • key:保存 key 和 value 的信息,它作为 best effort 提供,在 在某些情况下,它可能为 NULL,在这种情况下,用户应该(可以)使用RedisModule_OpenKey()(以及 CloseKey)。 当它被提供时,它由调用方拥有,并且当 callback 返回。
  • privdata:提供给RedisModule_Scan().

应该使用的方式是:

 RedisModuleScanCursor *c = RedisModule_ScanCursorCreate();
 while(RedisModule_Scan(ctx, c, callback, privateData));
 RedisModule_ScanCursorDestroy(c);

也可以在锁定 在实际调用RedisModule_Scan:

 RedisModuleScanCursor *c = RedisModule_ScanCursorCreate();
 RedisModule_ThreadSafeContextLock(ctx);
 while(RedisModule_Scan(ctx, c, callback, privateData)){
     RedisModule_ThreadSafeContextUnlock(ctx);
     // do some background job
     RedisModule_ThreadSafeContextLock(ctx);
 }
 RedisModule_ScanCursorDestroy(c);

如果有更多元素要扫描,该函数将返回 1,并且 否则为 0,如果调用失败,则可能设置 errno。

也可以使用RedisModule_ScanCursorRestart.

重要提示:此 API 与 Redis SCAN 命令非常相似 从它提供的保证的角度来看。这意味着 API 可以报告重复的键,但保证至少报告一次 从扫描过程开始到结束的每个键都在那里。

注意:如果您在回调中执行数据库更改,则应注意 数据库的内部状态可能会更改。例如,它是安全的 删除或修改当前密钥,但可能不安全地删除任何 其他键。 此外,在迭代时使用 Redis 键空间可能会有 返回更多重复项的效果。一种安全的模式是存储密钥 名称,然后对键执行作 稍后在迭代完成时。但是,这可能会花费很多 memory,因此在 在迭代期间可能,前提是这是安全的。

RedisModule_ScanKey

int RedisModule_ScanKey(RedisModuleKey *key,
                        RedisModuleScanCursor *cursor,
                        RedisModuleScanKeyCB fn,
                        void *privdata);

从以下版本可用: 6.0.0

允许模块扫描 hash、set 或 sorted set key 中的元素的 Scan API

扫描实现的回调。

void scan_callback(RedisModuleKey *key, RedisModuleString* field, RedisModuleString* value, void *privdata);
  • key - 为扫描提供的 Redis 键上下文。
  • field - 字段名称,由调用方拥有,如果使用,则需要保留 在此功能之后。
  • value - 值字符串或 NULL 表示设置类型,由调用方拥有,需要 如果在此功能之后使用,则保留。
  • PrivData - 提供给RedisModule_ScanKey.

应该使用的方式是:

 RedisModuleScanCursor *c = RedisModule_ScanCursorCreate();
 RedisModuleKey *key = RedisModule_OpenKey(...)
 while(RedisModule_ScanKey(key, c, callback, privateData));
 RedisModule_CloseKey(key);
 RedisModule_ScanCursorDestroy(c);

在 对RedisModule_ScanKey,并每次重新打开密钥:

 RedisModuleScanCursor *c = RedisModule_ScanCursorCreate();
 RedisModule_ThreadSafeContextLock(ctx);
 RedisModuleKey *key = RedisModule_OpenKey(...)
 while(RedisModule_ScanKey(ctx, c, callback, privateData)){
     RedisModule_CloseKey(key);
     RedisModule_ThreadSafeContextUnlock(ctx);
     // do some background job
     RedisModule_ThreadSafeContextLock(ctx);
     RedisModuleKey *key = RedisModule_OpenKey(...)
 }
 RedisModule_CloseKey(key);
 RedisModule_ScanCursorDestroy(c);

如果有更多元素需要扫描,该函数将返回 1,否则返回 0, 如果调用失败,则可能设置 errno。 也可以使用RedisModule_ScanCursorRestart.

注意:迭代对象时,某些作是不安全的。例如 而 API 保证至少返回一次 从头到尾始终存在于数据结构中 迭代中(请参阅 HSCAN 和类似命令文档),则 你玩元素,你可能会得到越多的重复项。通常 删除数据结构的当前元素是安全的,而删除 您正在迭代的 key is not safe。

模块 fork API

RedisModule_Fork

int RedisModule_Fork(RedisModuleForkDoneHandler cb, void *user_data);

从以下版本可用: 6.0.0

使用 main 进程,你可以在后台进行一些处理,而无需 影响 / 冻结流量,无需线程和 GIL 锁定。 请注意,Redis 只允许一个并发 fork。 当子进程想要退出时,它应该调用RedisModule_ExitFromChild. 如果父级想要杀死子级,它应该调用RedisModule_KillForkChilddone 处理程序回调将在父进程上执行,当 孩子存在(但不是被杀死时) 返回:失败时为 -1,成功时父进程将获得正 PID 子进程,子进程将得到 0。

RedisModule_SendChildHeartbeat

void RedisModule_SendChildHeartbeat(double progress);

从以下版本可用: 6.2.0

建议模块偶尔从 fork 子节点调用此函数, 这样它就可以向父级报告进度和 COW 内存,这将是 在 INFO 中报告。 这progress参数应介于 0 和 1 之间,如果不可用,则为 -1。

RedisModule_ExitFromChild

int RedisModule_ExitFromChild(int retcode);

从以下版本可用: 6.0.0

当您想要终止子进程时,从子进程调用。 retcode 将提供给在父进程上执行的 done 处理程序。

RedisModule_KillForkChild

int RedisModule_KillForkChild(int child_pid);

从以下版本可用: 6.0.0

可用于从父进程中终止分叉的子进程。child_pid将是RedisModule_Fork.

服务器钩子实现

RedisModule_SubscribeToServerEvent

int RedisModule_SubscribeToServerEvent(RedisModuleCtx *ctx,
                                       RedisModuleEvent event,
                                       RedisModuleEventCallback callback);

从以下版本可用: 6.0.0

注册以在指定的服务器事件 发生。调用回调时,将事件作为参数,并附加一个 argument 的 Case,该参数是 void 指针,应大小写为特定类型 这是特定于事件的(但许多事件将只使用 NULL,因为它们不使用 NULL 有其他信息要传递给回调)。

如果回调为 NULL 并且之前有订阅,则模块 将取消订阅。如果有以前的订阅和回调 不为空,则旧回调将被新回调替换。

回调必须为以下类型:

int (*RedisModuleEventCallback)(RedisModuleCtx *ctx,
                                RedisModuleEvent eid,
                                uint64_t subevent,
                                void *data);

'ctx' 是回调可以在其中使用的普通 Redis 模块上下文 order 调用其他模块 API。“开斋节”是事件本身,这个 仅在模块订阅多个事件的情况下才有用:使用 此结构的 'id' 字段可以检查事件 是我们在此回调中注册的事件之一。'subevent' 字段 取决于触发的事件。

最后,'data' 指针可以填充,但仅针对某些事件,使用 更相关的数据。

以下是可用作 'eid' 的事件和相关子事件的列表:

  • RedisModuleEvent_ReplicationRoleChanged:

    当实例从 master 切换时调用此事件 复制到 replica 或相反,但事件是 当副本仍为副本但开始 使用不同的 master 进行复制。

    以下子事件可用:

    • REDISMODULE_SUBEVENT_REPLROLECHANGED_NOW_MASTER
    • REDISMODULE_SUBEVENT_REPLROLECHANGED_NOW_REPLICA

    回调可以将 'data' 字段转换为RedisModuleReplicationInfo结构体中具有以下字段:

      int master; // true if master, false if replica
      char *masterhost; // master instance hostname for NOW_REPLICA
      int masterport; // master instance port for NOW_REPLICA
      char *replid1; // Main replication ID
      char *replid2; // Secondary replication ID
      uint64_t repl1_offset; // Main replication offset
      uint64_t repl2_offset; // Offset of replid2 validity
    
  • RedisModuleEvent_Persistence

    当 RDB 保存或 AOF 重写开始时,将调用此事件 并结束。以下子事件可用:

    • REDISMODULE_SUBEVENT_PERSISTENCE_RDB_START
    • REDISMODULE_SUBEVENT_PERSISTENCE_AOF_START
    • REDISMODULE_SUBEVENT_PERSISTENCE_SYNC_RDB_START
    • REDISMODULE_SUBEVENT_PERSISTENCE_SYNC_AOF_START
    • REDISMODULE_SUBEVENT_PERSISTENCE_ENDED
    • REDISMODULE_SUBEVENT_PERSISTENCE_FAILED

    上述事件不仅在用户调用 相关命令(如 BGSAVE),以及当保存作 或 AOF 重写是由于内部服务器触发器而发生的。 SYNC_RDB_START由于 SAVE 命令、FLUSHALL 或服务器关闭,以及其他 RDB 和 AOF 子事件在后台 fork 子事件中执行,因此任何 模块采取的作只能影响生成的 AOF 或 RDB, 但不会反映在父流程中,并影响 Connected 客户端和命令。另请注意,AOF_START 子事件可能会结束 在使用 rdb-preamble 的 AOF 的情况下保存 RDB 内容。

  • RedisModuleEvent_FlushDB

    FLUSHALL、FLUSHDB 或内部 flush(例如 因为复制,在副本同步之后) 发生。以下子事件可用:

    • REDISMODULE_SUBEVENT_FLUSHDB_START
    • REDISMODULE_SUBEVENT_FLUSHDB_END

    数据指针可以强制转换为 RedisModuleFlushInfo 结构体中具有以下字段:

      int32_t async;  // True if the flush is done in a thread.
                      // See for instance FLUSHALL ASYNC.
                      // In this case the END callback is invoked
                      // immediately after the database is put
                      // in the free list of the thread.
      int32_t dbnum;  // Flushed database number, -1 for all the DBs
                      // in the case of the FLUSHALL operation.
    

    在启动作之前调用 start 事件,因此 允许回调调用 DBSIZE 或其他对 尚未释放的密钥空间。

  • RedisModuleEvent_Loading

    在加载作时调用:启动时,当服务器处于 started,但在第一次同步后,当 replica 正在从主服务器加载 RDB 文件。 以下子事件可用:

    • REDISMODULE_SUBEVENT_LOADING_RDB_START
    • REDISMODULE_SUBEVENT_LOADING_AOF_START
    • REDISMODULE_SUBEVENT_LOADING_REPL_START
    • REDISMODULE_SUBEVENT_LOADING_ENDED
    • REDISMODULE_SUBEVENT_LOADING_FAILED

    请注意,在以下情况下,AOF 加载可能从 RDB 数据开始 rdb-preamble 中,在这种情况下,您只会收到一个 AOF_START 事件。

  • RedisModuleEvent_ClientChange

    在客户端连接或断开连接时调用。 数据指针可以强制转换为 RedisModuleClientInfo 结构,记录在 RedisModule_GetClientInfoById() 中。 以下子事件可用:

    • REDISMODULE_SUBEVENT_CLIENT_CHANGE_CONNECTED
    • REDISMODULE_SUBEVENT_CLIENT_CHANGE_DISCONNECTED
  • RedisModuleEvent_Shutdown

    服务器正在关闭。没有可用的子事件。

  • RedisModuleEvent_ReplicaChange

    当实例(可以是 master 或 a replica)获取新的在线副本,否则会丢失 replica 的 Notebook 副本。 以下子事件可用:

    • REDISMODULE_SUBEVENT_REPLICA_CHANGE_ONLINE
    • REDISMODULE_SUBEVENT_REPLICA_CHANGE_OFFLINE

    目前没有其他信息可用:未来版本 的 Redis 将具有一个 API 来枚举副本 connected 及其状态。

  • RedisModuleEvent_CronLoop

    每次 Redis 调用 serverCron() 时都会调用此事件 功能进行某些记账。模块 需要时不时做作可以使用这个回调。 通常 Redis 每秒调用此函数 10 次,但 这取决于 “Hz” 配置。 没有可用的子事件。

    数据指针可以强制转换为 RedisModuleCronLoop 结构体中具有以下字段:

      int32_t hz;  // Approximate number of events per second.
    
  • RedisModuleEvent_MasterLinkChange

    这是对副本调用的,以便在 复制链接与我们的 master 一起变得功能化 (UP), 或者当它下降时。请注意,不考虑该链接 up 时,但前提是 复制正在正确进行。 以下子事件可用:

    • REDISMODULE_SUBEVENT_MASTER_LINK_UP
    • REDISMODULE_SUBEVENT_MASTER_LINK_DOWN
  • RedisModuleEvent_ModuleChange

    当加载新模块或卸载新模块时,将调用此事件。 以下子事件可用:

    • REDISMODULE_SUBEVENT_MODULE_LOADED
    • REDISMODULE_SUBEVENT_MODULE_UNLOADED

    数据指针可以强制转换为 RedisModuleModuleChange 结构体中具有以下字段:

      const char* module_name;  // Name of module loaded or unloaded.
      int32_t module_version;  // Module version.
    
  • RedisModuleEvent_LoadingProgress

    当 RDB 或 AOF 文件时,将重复调用此事件 正在加载。 以下子事件可用:

    • REDISMODULE_SUBEVENT_LOADING_PROGRESS_RDB
    • REDISMODULE_SUBEVENT_LOADING_PROGRESS_AOF

    数据指针可以强制转换为 RedisModuleLoadingProgress 结构体中具有以下字段:

      int32_t hz;  // Approximate number of events per second.
      int32_t progress;  // Approximate progress between 0 and 1024,
                         // or -1 if unknown.
    
  • RedisModuleEvent_SwapDB

    当 SWAPDB 命令成功时,将调用此事件 执行。 对于此事件调用,当前没有可用的子事件。

    数据指针可以强制转换为 RedisModuleSwapDbInfo 结构体中具有以下字段:

      int32_t dbnum_first;    // Swap Db first dbnum
      int32_t dbnum_second;   // Swap Db second dbnum
    
  • RedisModuleEvent_ReplBackup

    警告:复制备份事件自 Redis 7.0 起已弃用,并且永远不会触发。 请参阅 RedisModuleEvent_ReplAsyncLoad 以了解异步复制加载事件 现在,当 repl-diskless-load 设置为 swapdb 时触发。

    当 repl-diskless-load config 设置为 swapdb 时调用, 而 redis 需要备份当前数据库,以便 以后恢复的可能性。具有全局数据 和 也许 with aux_load 和 aux_save 回调可能需要使用 this 通知备份/恢复/丢弃其全局变量。 以下子事件可用:

    • REDISMODULE_SUBEVENT_REPL_BACKUP_CREATE
    • REDISMODULE_SUBEVENT_REPL_BACKUP_RESTORE
    • REDISMODULE_SUBEVENT_REPL_BACKUP_DISCARD
  • RedisModuleEvent_ReplAsyncLoad

    当 repl-diskless-load config 设置为 swapdb 且 master 具有相同的 master 时调用 出现数据集历史记录(与复制 ID 匹配)。 在这种情况下,redis 在从 socket 加载新数据库到内存时提供当前数据集。 模块必须声明它们支持此机制才能激活它,通过 REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD标志。 以下子事件可用:

    • REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_STARTED
    • REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_ABORTED
    • REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_COMPLETED
  • RedisModuleEvent_ForkChild

    当 fork 子项(AOFRW、RDBSAVE、模块 fork...)出生/消亡时调用 以下子事件可用:

    • REDISMODULE_SUBEVENT_FORK_CHILD_BORN
    • REDISMODULE_SUBEVENT_FORK_CHILD_DIED
  • RedisModuleEvent_EventLoop

    在每次事件循环迭代时调用,在事件循环开始之前调用一次 进入睡眠状态或刚醒来后。 以下子事件可用:

    • REDISMODULE_SUBEVENT_EVENTLOOP_BEFORE_SLEEP
    • REDISMODULE_SUBEVENT_EVENTLOOP_AFTER_SLEEP
  • RedisModule_Event_Config

    发生配置事件时调用 以下子事件可用:

    • REDISMODULE_SUBEVENT_CONFIG_CHANGE

    数据指针可以强制转换为 RedisModuleConfigChange 结构体中具有以下字段:

      const char **config_names; // An array of C string pointers containing the
                                 // name of each modified configuration item 
      uint32_t num_changes;      // The number of elements in the config_names array
    
  • RedisModule_Event_Key

    从键空间中删除键时调用。我们不能修改 事件。 以下子事件可用:

    • REDISMODULE_SUBEVENT_KEY_DELETED
    • REDISMODULE_SUBEVENT_KEY_EXPIRED
    • REDISMODULE_SUBEVENT_KEY_EVICTED
    • REDISMODULE_SUBEVENT_KEY_OVERWRITTEN

    数据指针可以强制转换为 RedisModuleKeyInfo 结构体中具有以下字段:

      RedisModuleKey *key;    // Key name
    

该函数返回REDISMODULE_OK如果模块订阅成功 对于指定的事件。如果 API 是从错误的上下文或不受支持的事件调用的 则给出REDISMODULE_ERR返回。

RedisModule_IsSubEventSupported

int RedisModule_IsSubEventSupported(RedisModuleEvent event, int64_t subevent);

从以下版本可用: 6.0.9

对于给定的服务器事件和子事件,如果 subevent 不受支持,否则为非零。

模块配置 API

RedisModule_RegisterStringConfig

int RedisModule_RegisterStringConfig(RedisModuleCtx *ctx,
                                     const char *name,
                                     const char *default_val,
                                     unsigned int flags,
                                     RedisModuleConfigGetStringFunc getfn,
                                     RedisModuleConfigSetStringFunc setfn,
                                     RedisModuleConfigApplyFunc applyfn,
                                     void *privdata);

从以下版本可用: 7.0.0

创建一个字符串配置,Redis 用户可以通过 Redis 配置文件与之交互,CONFIG SET,CONFIG GETCONFIG REWRITE命令。

实际的 config 值归模块所有,而getfn,setfn和可选applyfn回调,以便访问或作 价值。这getfncallback 从模块中检索值,而setfncallback 提供要存储到模块配置中的值。 可选的applyfncallback 在CONFIG SET命令修改为 1 或 使用setfncallback 的 API 中,可用于原子地应用配置 几个配置一起更改后。 如果有多个配置,并且applyfn由单个CONFIG SET命令,如果它们的applyfnfunction 和privdata指针 相同,则回调只会运行一次。 这setfnapplyfn如果提供的值无效,则可能返回错误,或者 不能使用。 该配置还为值声明了一个类型,该类型由 Redis 验证,并且 提供给模块。config 系统提供以下类型:

  • Redis 字符串:二进制安全字符串数据。
  • Enum:注册期间提供的有限数量的字符串标记之一。
  • Numeric:64 位有符号整数,也支持 min 和 max 值。
  • Bool:是或无值。

setfncallback 应返回REDISMODULE_OK当值成功时 应用的。它也可以返回REDISMODULE_ERR如果该值无法应用,并且 *err 指针可以使用RedisModuleString要提供给客户端的错误消息。 这RedisModuleString将从 set 回调返回后被 Redis 释放。

所有配置都使用名称、类型、默认值、私有数据进行注册 ,以及修改配置行为的几个标志。 名称只能包含字母数字字符或短划线。支持的标志包括:

  • REDISMODULE_CONFIG_DEFAULT:配置的默认标志。这将创建一个可在启动后修改的配置。
  • REDISMODULE_CONFIG_IMMUTABLE:此配置只能提供加载时间。
  • REDISMODULE_CONFIG_SENSITIVE:此配置中存储的值将从所有日志记录中编辑。
  • REDISMODULE_CONFIG_HIDDEN:名称隐藏在CONFIG GET具有模式匹配。
  • REDISMODULE_CONFIG_PROTECTED:此配置只能根据 enable-protected-configurations 的值进行修改。
  • REDISMODULE_CONFIG_DENY_LOADING:当服务器加载数据时,此配置不可修改。
  • REDISMODULE_CONFIG_MEMORY:对于数字配置,此配置会将数据单位表示法转换为其等效字节。
  • REDISMODULE_CONFIG_BITFLAGS:对于枚举配置,此配置将允许将多个条目组合为位标志。

如果未通过配置文件提供默认值,则在启动时使用默认值来设置该值 或命令行。默认值也用于比较配置重写时的值。

笔记:

  1. 在 string config 上,设置传递给 set 回调的字符串在执行后将被释放,并且模块必须保留它。
  2. 在 string config 获取时,字符串不会被消耗,并且在执行后仍然有效。

示例实现:

RedisModuleString *strval;
int adjustable = 1;
RedisModuleString *getStringConfigCommand(const char *name, void *privdata) {
    return strval;
}

int setStringConfigCommand(const char *name, RedisModuleString *new, void *privdata, RedisModuleString **err) {
   if (adjustable) {
       RedisModule_Free(strval);
       RedisModule_RetainString(NULL, new);
       strval = new;
       return REDISMODULE_OK;
   }
   *err = RedisModule_CreateString(NULL, "Not adjustable.", 15);
   return REDISMODULE_ERR;
}
...
RedisModule_RegisterStringConfig(ctx, "string", NULL, REDISMODULE_CONFIG_DEFAULT, getStringConfigCommand, setStringConfigCommand, NULL, NULL);

如果注册失败,REDISMODULE_ERR将返回,并且是以下其中一项 errno 的 set:

  • EBUSY:在 Config 之外注册RedisModule_OnLoad.
  • EINVAL:提供的标志对于注册无效,或者配置名称包含无效字符。
  • EALREADY:提供的配置名称已使用。

RedisModule_RegisterBoolConfig

int RedisModule_RegisterBoolConfig(RedisModuleCtx *ctx,
                                   const char *name,
                                   int default_val,
                                   unsigned int flags,
                                   RedisModuleConfigGetBoolFunc getfn,
                                   RedisModuleConfigSetBoolFunc setfn,
                                   RedisModuleConfigApplyFunc applyfn,
                                   void *privdata);

从以下版本可用: 7.0.0

创建一个 bool 配置,服务器客户端可以通过CONFIG SET,CONFIG GETCONFIG REWRITE命令。看RedisModule_RegisterStringConfig了解有关配置的详细信息。

RedisModule_RegisterEnumConfig

int RedisModule_RegisterEnumConfig(RedisModuleCtx *ctx,
                                   const char *name,
                                   int default_val,
                                   unsigned int flags,
                                   const char **enum_values,
                                   const int *int_values,
                                   int num_enum_vals,
                                   RedisModuleConfigGetEnumFunc getfn,
                                   RedisModuleConfigSetEnumFunc setfn,
                                   RedisModuleConfigApplyFunc applyfn,
                                   void *privdata);

从以下版本可用: 7.0.0

创建一个 enum 配置,服务器客户端可以通过CONFIG SET,CONFIG GETCONFIG REWRITE命令。 枚举配置是一组字符串标记,对应于相应的整数值,其中 字符串值向 Redis 客户端公开,但该值传递了 Redis 和 module 是整数值。这些值在enum_values、数组 以 null 结尾的 c 字符串,以及int_vals,一个枚举值数组,其 指数合作伙伴enum_values. 示例实现: const char *enum_vals[3] = {“第一”, “第二”, “第三”}; const int int_vals[3] = {0, 2, 4}; int enum_val = 0;

 int getEnumConfigCommand(const char *name, void *privdata) {
     return enum_val;
 }
  
 int setEnumConfigCommand(const char *name, int val, void *privdata, const char **err) {
     enum_val = val;
     return REDISMODULE_OK;
 }
 ...
 RedisModule_RegisterEnumConfig(ctx, "enum", 0, REDISMODULE_CONFIG_DEFAULT, enum_vals, int_vals, 3, getEnumConfigCommand, setEnumConfigCommand, NULL, NULL);

请注意,您可以使用REDISMODULE_CONFIG_BITFLAGS因此,多个枚举字符串 可以作为位标志组合成一个整数,在这种情况下,您可能希望 对枚举进行排序,以便首选组合首先出现。

RedisModule_RegisterStringConfig了解有关配置的详细一般信息。

RedisModule_RegisterNumericConfig

int RedisModule_RegisterNumericConfig(RedisModuleCtx *ctx,
                                      const char *name,
                                      long long default_val,
                                      unsigned int flags,
                                      long long min,
                                      long long max,
                                      RedisModuleConfigGetNumericFunc getfn,
                                      RedisModuleConfigSetNumericFunc setfn,
                                      RedisModuleConfigApplyFunc applyfn,
                                      void *privdata);

从以下版本可用: 7.0.0

创建一个整数配置,服务器客户端可以通过CONFIG SET,CONFIG GETCONFIG REWRITE命令。看RedisModule_RegisterStringConfig了解有关配置的详细信息。

RedisModule_LoadConfigs

int RedisModule_LoadConfigs(RedisModuleCtx *ctx);

从以下版本可用: 7.0.0

在模块加载时应用所有待处理的配置。这应该称为 在为 模块内部的RedisModule_OnLoad. 这将返回REDISMODULE_ERR如果它在 Outside 调用RedisModule_OnLoad. 当在MODULE LOADEX或作为启动参数提供。

RDB 加载/保存 API

RedisModule_RdbStreamCreateFromFile

RedisModuleRdbStream *RedisModule_RdbStreamCreateFromFile(const char *filename);

从以下版本可用: 7.2.0

创建流对象以将 RDB 保存/加载到文件中或从文件中加载 RDB。

此函数返回一个指向RedisModuleRdbStream哪个是 由调用方。它需要调用RedisModule_RdbStreamFree()免费 对象。

RedisModule_RdbStreamFree

void RedisModule_RdbStreamFree(RedisModuleRdbStream *stream);

从以下版本可用: 7.2.0

释放 RDB 流对象。

RedisModule_RdbLoad

int RedisModule_RdbLoad(RedisModuleCtx *ctx,
                        RedisModuleRdbStream *stream,
                        int flags);

从以下版本可用: 7.2.0

stream.将首先清除数据集,然后清除 RDB 文件。

flags必须为零。此参数供将来使用。

成功时REDISMODULE_OK返回,否则REDISMODULE_ERR返回 并相应地设置 errno。

例:

RedisModuleRdbStream *s = RedisModule_RdbStreamCreateFromFile("exp.rdb");
RedisModule_RdbLoad(ctx, s, 0);
RedisModule_RdbStreamFree(s);

RedisModule_RdbSave

int RedisModule_RdbSave(RedisModuleCtx *ctx,
                        RedisModuleRdbStream *stream,
                        int flags);

从以下版本可用: 7.2.0

将数据集保存到 RDB 流。

flags必须为零。此参数供将来使用。

成功时REDISMODULE_OK返回,否则REDISMODULE_ERR返回 并相应地设置 errno。

例:

RedisModuleRdbStream *s = RedisModule_RdbStreamCreateFromFile("exp.rdb");
RedisModule_RdbSave(ctx, s, 0);
RedisModule_RdbStreamFree(s);

密钥驱逐 API

RedisModule_SetLRU

int RedisModule_SetLRU(RedisModuleKey *key, mstime_t lru_idle);

从以下版本可用: 6.0.0

为基于 LRU 的驱逐设置密钥上次访问时间。如果 servers 的 maxmemory 策略基于 LFU。值是空闲时间(以毫秒为单位)。 返回REDISMODULE_OK如果 LRU 已更新,REDISMODULE_ERR否则。

RedisModule_GetLRU

int RedisModule_GetLRU(RedisModuleKey *key, mstime_t *lru_idle);

从以下版本可用: 6.0.0

获取密钥上次访问时间。 值为 idletime(以毫秒为单位),如果服务器的驱逐策略为 -1 基于 LFU。 返回REDISMODULE_OKif when key 有效。

RedisModule_SetLFU

int RedisModule_SetLFU(RedisModuleKey *key, long long lfu_freq);

从以下版本可用: 6.0.0

设置密钥访问频率。仅当服务器的 maxMemory 策略 基于 LFU。 频率是一个对数计数器,它指示 Access frequencyOnly(必须为 <= 255)。 返回REDISMODULE_OK如果 LFU 已更新,REDISMODULE_ERR否则。

RedisModule_GetLFU

int RedisModule_GetLFU(RedisModuleKey *key, long long *lfu_freq);

从以下版本可用: 6.0.0

获取密钥访问频率,如果服务器的逐出策略不是 -1 基于 LFU。 返回REDISMODULE_OKif when key 有效。

其他 API

RedisModule_GetModuleOptionsAll

int RedisModule_GetModuleOptionsAll(void);

从以下版本可用: 7.2.0

使用返回值返回完整的模块 options flags mask 该模块可以检查是否支持某组 Module 选项 按正在使用的 Redis 服务器版本。 例:

   int supportedFlags = RedisModule_GetModuleOptionsAll();
   if (supportedFlags & REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS) {
         // REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS is supported
   } else{
         // REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS is not supported
   }

RedisModule_GetContextFlagsAll

int RedisModule_GetContextFlagsAll(void);

从以下版本可用: 6.0.9

使用返回值返回完整的 ContextFlags 掩码 该模块可以检查是否支持一组特定的标志 按正在使用的 Redis 服务器版本。 例:

   int supportedFlags = RedisModule_GetContextFlagsAll();
   if (supportedFlags & REDISMODULE_CTX_FLAGS_MULTI) {
         // REDISMODULE_CTX_FLAGS_MULTI is supported
   } else{
         // REDISMODULE_CTX_FLAGS_MULTI is not supported
   }

RedisModule_GetKeyspaceNotificationFlagsAll

int RedisModule_GetKeyspaceNotificationFlagsAll(void);

从以下版本可用: 6.0.9

使用返回值返回完整的 KeyspaceNotification 掩码 该模块可以检查是否支持一组特定的标志 按正在使用的 Redis 服务器版本。 例:

   int supportedFlags = RedisModule_GetKeyspaceNotificationFlagsAll();
   if (supportedFlags & REDISMODULE_NOTIFY_LOADED) {
         // REDISMODULE_NOTIFY_LOADED is supported
   } else{
         // REDISMODULE_NOTIFY_LOADED is not supported
   }

RedisModule_GetServerVersion

int RedisModule_GetServerVersion(void);

从以下版本可用: 6.0.9

返回 redis 版本,格式为 0x00MMmmpp。 对于 6.0.7 的示例,返回值将为 0x00060007。

RedisModule_GetTypeMethodVersion

int RedisModule_GetTypeMethodVersion(void);

从以下版本可用: 6.2.0

返回REDISMODULE_TYPE_METHOD_VERSION. 您可以在调用RedisModule_CreateDataType要了解RedisModuleTypeMethods将受到支持,而这些将被忽略。

RedisModule_ModuleTypeReplaceValue

int RedisModule_ModuleTypeReplaceValue(RedisModuleKey *key,
                                       moduleType *mt,
                                       void *new_value,
                                       void **old_value);

从以下版本可用: 6.0.0

替换分配给模块类型的值。

键必须打开以供写入,具有现有值,并且具有 moduleType 与调用方指定的值匹配。

RedisModule_ModuleTypeSetValue()这将释放旧值,此函数 只需将旧值与新值交换即可。

该函数返回REDISMODULE_OK成功时,REDISMODULE_ERR错误时 如:

  1. 密钥未打开进行写入。
  2. key 不是模块数据类型的 key。
  3. Key 是除 'mt' 以外的模块数据类型。

如果old_value为非 NULL,则通过引用返回旧值。

RedisModule_GetCommandKeysWithFlags

int *RedisModule_GetCommandKeysWithFlags(RedisModuleCtx *ctx,
                                         RedisModuleString **argv,
                                         int argc,
                                         int *num_keys,
                                         int **out_flags);

从以下版本可用: 7.0.0

对于指定的命令,解析其参数并返回一个数组,该数组 包含所有键名称参数的索引。此功能为 本质上是一种更有效的方法COMMAND GETKEYS.

out_flags参数是可选的,可以设置为 NULL。 当提供时,它填充有REDISMODULE_CMD_KEY_匹配的标志 indexes 替换为返回数组的键索引。

NULL 返回值表示指定的命令没有键,或者 错误条件。错误情况通过设置 errno 来指示 如下:

  • ENOENT:指定的命令不存在。
  • EINVAL:指定的命令 arity 无效。

注意:返回的数组不是 Redis Module 对象,因此它不会 即使使用自动内存,也会自动释放。调用方 必须显式调用RedisModule_Free()以释放它,与out_flagspointer 如果 使用。

RedisModule_GetCommandKeys

int *RedisModule_GetCommandKeys(RedisModuleCtx *ctx,
                                RedisModuleString **argv,
                                int argc,
                                int *num_keys);

从以下版本可用: 6.0.9

等同于RedisModule_GetCommandKeysWithFlags当不需要标志时。

RedisModule_GetCurrentCommandName

const char *RedisModule_GetCurrentCommandName(RedisModuleCtx *ctx);

从以下版本可用: 6.2.5

返回当前正在运行的命令的名称

碎片整理 API

RedisModule_RegisterDefragFunc

int RedisModule_RegisterDefragFunc(RedisModuleCtx *ctx,
                                   RedisModuleDefragFunc cb);

从以下版本可用: 6.2.0

为全局数据注册一个碎片整理回调,即模块 可以分配,这与特定数据类型无关。

RedisModule_DefragShouldStop

int RedisModule_DefragShouldStop(RedisModuleDefragCtx *ctx);

从以下版本可用: 6.2.0

当数据类型 defrag 回调迭代复杂结构时,这个 function 应该定期调用。零 (false) 返回 表示回调可以继续工作。非零值 (true) 表示它应该停止。

停止后,回调可能会使用RedisModule_DefragCursorSet()来存储其 position 以便以后可以使用RedisModule_DefragCursorGet()以恢复碎片整理。

当停止并且还有更多工作要完成时,回调应该 返回 1.否则,它应该返回 0。

注意: 模块应考虑调用此函数的频率, 因此,在两次调用之间执行小批量工作通常是有意义的。

RedisModule_DefragCursorSet

int RedisModule_DefragCursorSet(RedisModuleDefragCtx *ctx,
                                unsigned long cursor);

从以下版本可用: 6.2.0

存储任意游标值以供将来重用。

只有在以下情况下才应调用RedisModule_DefragShouldStop()返回了非零 值,并且碎片整理回调即将退出,而没有完全迭代其 数据类型。

此行为保留给执行延迟碎片整理的情况。晚 defrag 为实现free_effortcallback 和 返回一个free_effort大于碎片整理的值 'active-defrag-max-scan-fields' 配置指令。

较小的 key,未实现的 keyfree_effort或全局 defrag 回调在 Late-defrag 模式下不会调用。在这些情况下, 调用此函数将返回REDISMODULE_ERR.

该光标可以被模块用来表示 module 的数据类型。模块还可以存储其他与游标相关的 信息,并使用光标作为标志来指示何时 开始遍历新 key。这是可能的,因为 API 使 保证多个键的并发碎片整理将 不执行。

RedisModule_DefragCursorGet

int RedisModule_DefragCursorGet(RedisModuleDefragCtx *ctx,
                                unsigned long *cursor);

从以下版本可用: 6.2.0

获取以前使用RedisModule_DefragCursorSet().

如果未要求进行后期碎片整理作,REDISMODULE_ERR将返回,并且 应忽略光标。看RedisModule_DefragCursorSet()有关更多详细信息 碎片整理游标。

RedisModule_DefragAlloc

void *RedisModule_DefragAlloc(RedisModuleDefragCtx *ctx, void *ptr);

从以下版本可用: 6.2.0

对之前由 分配的内存分配进行碎片整理RedisModule_Alloc,RedisModule_Calloc等。 碎片整理过程包括分配新的内存块和复制 它的内容,比如realloc().

如果不需要碎片整理,则返回 NULL,并且作具有 没有其他效果。

如果返回非 NULL 值,则调用方应改用新指针 的 URL 中,并更新对旧指针的任何引用,该指针不得 再次使用。

RedisModule_DefragRedisModuleString

RedisModuleString *RedisModule_DefragRedisModuleString(RedisModuleDefragCtx *ctx,
                                                       RedisModuleString *str);

从以下版本可用: 6.2.0

碎片整理RedisModuleString之前分配者RedisModule_Alloc,RedisModule_Calloc等。 看RedisModule_DefragAlloc()了解有关碎片整理过程的更多信息 工程。

注意:只能对具有单个引用的字符串进行碎片整理。 通常,这意味着保留有RedisModule_RetainStringRedisModule_HoldString可能无法进行碎片整理。一个例外是命令 argvs,如果保留 将得到一个引用(因为 在 Redis 端,命令回调返回后立即删除)。

RedisModule_GetKeyNameFromDefragCtx

const RedisModuleString *RedisModule_GetKeyNameFromDefragCtx(RedisModuleDefragCtx *ctx);

从以下版本可用: 7.0.0

返回当前正在处理的键的名称。 不能保证键名称始终可用,因此这可能会返回 NULL。

RedisModule_GetDbIdFromDefragCtx

int RedisModule_GetDbIdFromDefragCtx(RedisModuleDefragCtx *ctx);

从以下版本可用: 7.0.0

返回当前正在处理的密钥的数据库 ID。 不能保证此信息始终可用,因此可能会返回 -1。

功能指标

为本页评分
返回顶部 ↑