开始使用Redis模块

该文章是富士通云技术的2018年圣诞节日程的第13天。
昨天是@Ken-Moriizumi先生的“年底大扫除积压物品”的故事。

Redis模块初探

你好,我是@blue271828。我有一段时间没有接触Redis了,但我发现它已经添加了一个新的功能叫做Redis模块。这个功能很棒,能够解决Lua脚本功能无法达到的需求。我想介绍一下这个功能。

Redis模块是什么

Redis Module 是从 Redis 4.0 开始新增的功能,它允许通过加载用 C、C++ 实现的模块到 Redis 中,实现各种扩展功能的机制。例如,可以通过一条命令同时操作多个键,也可以创建自定义数据类型。

试一试

请包含redismodule.h头文件并实现以下内容。使用参数字符串作为键,将”Hello, World!”添加到列表类型的简单处理。

#include "redismodule.h"
#include <stdlib.h>
#include <string.h>

int HelloWorld_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
  /* 引数の数をチェック */
  if (argc != 2) return RedisModule_WrongArity(ctx);


  /* 引数の値をkeyにしてLPUSH */
  const char *hello = "Hello, World!";
  RedisModuleKey *key =RedisModule_OpenKey(ctx, argv[1], REDISMODULE_WRITE);
  RedisModuleString *str = RedisModule_CreateString(ctx, hello, strlen(hello));
  if (RedisModule_ListPush(key, REDISMODULE_LIST_TAIL, str) == REDISMODULE_ERR)
    return REDISMODULE_ERR;
  RedisModule_CloseKey(key);

  /* クライアントに値を返却 */
  if (RedisModule_ReplyWithString(ctx, str) == REDISMODULE_ERR)
    return REDISMODULE_ERR;

  return REDISMODULE_OK;
}

int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
  if (RedisModule_Init(ctx, "helloworld", 1, REDISMODULE_APIVER_1)
      == REDISMODULE_ERR) return REDISMODULE_ERR;

  if (RedisModule_CreateCommand(ctx,"helloworld",
                                HelloWorld_RedisCommand, "write", 1, 1, 1) == REDISMODULE_ERR)
    return REDISMODULE_ERR;

  return REDISMODULE_OK;
}

可以通过将实施的文件加载到Redis中并进行编译后使用。编译步骤如下。

$ gcc -O2 -shared -fPIC helloworld.c -o helloworld.so

Redis有两种加载方式,一种是通过Redis客户端进行加载,另一种是通过类似redis.conf的配置文件进行加载。如果通过Redis客户端进行加载,可以按照以下方式输入,成功加载后会显示”OK”。

> MODULE LOAD /path/to/helloworld.so

在设置文件中,可以使用以下方式进行描述:

loadmodule /path/to/helloworld.so

试着动一动

当您使用在加载后实施的命令时,您可以确认它们可用。

127.0.0.1:6379> LRANGE hoge 0 -1
(empty list or set)
127.0.0.1:6379> HELLOWORLD hoge
"Hello, World!"
127.0.0.1:6379> HELLOWORLD hoge
"Hello, World!"
127.0.0.1:6379> LRANGE hoge 0 -1
1) "Hello, World!"
2) "Hello, World!"

在 Redis Cluster 的情况下,与普通命令一样,根据 key 的哈希值将命令重定向到每个节点上。需要注意的是,如果所有节点都没有加载模块,则重定向命令将变为“unknown command”错误,因此在 Redis Cluster 中使用模块需要预先在目标节点上加载。

127.0.0.1:7000> HELLOWORLD hoge
"Hello, World!"
127.0.0.1:7000> HELLOWORLD hogehoge
"Hello, World!"
127.0.0.1:7000> HELLOWORLD hogehogehoge
-> Redirected to slot [5990] located at 173.17.0.3:7001
"Hello, World!"

尾声

我认为通过将Redis扩展为命令的形式,可以在使用Lua脚本功能无法实现的情况下进行利用。个人而言,甚至只是不再需要通过哈希来调用已加载的处理逻辑,这已经非常方便了。虽然这次没有深入探讨,但我相信Redis模块可能还有其独特的扩展功能,如果有机会的话,我会再次介绍。

顺便提一下,明天好像 @foobaron 会讲一些关于网络的内容。敬请期待!

广告
将在 10 秒后关闭
bannerAds