开始使用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 会讲一些关于网络的内容。敬请期待!