两个比较有名的 redis 模块
- https://github.com/RedisBloom/RedisBloom
- https://github.com/RedisGraph/RedisGraph
redis 模块文档:https://redis.io/docs/latest/develop/reference/modules/
1. 模块代码
文件 hello.cc
#include "redismodule.h"
#include <stdlib.h>
int HelloworldRand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
RedisModule_ReplyWithLongLong(ctx,rand());
return REDISMODULE_OK;
}
const char * modulename = "helloworld";
const char * command = "helloworld.rand";
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
if (RedisModule_Init(ctx, modulename, 1, REDISMODULE_APIVER_1)
== REDISMODULE_ERR) return REDISMODULE_ERR;
if (RedisModule_CreateCommand(ctx, command,
HelloworldRand_RedisCommand, "fast random",
0, 0, 0) == REDISMODULE_ERR)
return REDISMODULE_ERR;
return REDISMODULE_OK;
}
- 模块的名字为 helloworld
- 模块的命令为 helloworld.rand
2. CMakeLists.txt
PROJECT (redis-module)
INCLUDE_DIRECTORIES (
${CMAKE_CURRENT_SOURCE_DIR}/../redis-7.4.1/src # 目的是引用 "redismodule.h"
)
LINK_DIRECTORIES (
${CMAKE_CURRENT_SOURCE_DIR}/target
)
ADD_LIBRARY (htmlparser_shared SHARED src/hello.cc)
SET_TARGET_PROPERTIES(htmlparser_shared PROPERTIES OUTPUT_NAME "hello") # 输出文件名 libhello.so
SET_TARGET_PROPERTIES(htmlparser_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1)
3. 加载模块
修改文件 redis.conf
,增加一行
loadmodule /root/workspace/hello/target/libhello.so
或者在执行命令的时候增加参数 --loadmodule
./src/redis-server --loadmodule /root/workspace/hello/target/libhello.so
4. 使用 redis-cli 查看加载的模块 动态加载/卸载模块
- 加载模块
MODULE LOAD /path/to/mymodule.so
- 查看已经加载的模块列表
> MODULE LIST
- 卸载模块
MODULE UNLOAD mymodule
5. 模块中可以使用的 API
- 初始化
int RedisModule_Init(RedisModuleCtx *ctx, const char *modulename,
int module_version, int api_version);
- 注册命令
int RedisModule_CreateCommand(RedisModuleCtx *ctx, const char *name,
RedisModuleCmdFunc cmdfunc, const char *strflags,
int firstkey, int lastkey, int keystep);
- 执行命令的函数
int mycommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
- 返回值
int RedisModule_ReplyWithLongLong(RedisModuleCtx *ctx, long long integer);
- 清理模块
int RedisModule_OnUnload(RedisModuleCtx *ctx);
In most cases, there is no need for special cleanup. When a module is unloaded, Redis will automatically unregister commands and unsubscribe from notifications. However in the case where a module contains some persistent memory or configuration, a module may include an optional RedisModule_OnUnload function. If a module provides this function, it will be invoked during the module unload process. The following is the function prototype: The OnUnload function may prevent module unloading by returning REDISMODULE_ERR. Otherwise, REDISMODULE_OK should be returned.
- 数字转字符串/字符串转数字
RedisModuleString *mystr = RedisModule_CreateStringFromLongLong(ctx,10);
# --
long long myval;
if (RedisModule_StringToLongLong(ctx,argv[1],&myval) == REDISMODULE_OK) {
/* Do something with 'myval' */
}
- 调用 redis 命令
RedisModuleCallReply *reply;
reply = RedisModule_Call(ctx,"INCRBY","sc",argv[1],"10");
- 返回值
RedisModule_ReplyWithError(RedisModuleCtx *ctx, const char *err);
REDISMODULE_ERRORMSG_WRONGTYPE
RedisModule_ReplyWithError(ctx,"ERR invalid arguments");
RedisModule_ReplyWithLongLong(ctx,12345);
RedisModule_ReplyWithSimpleString(ctx,"OK");
int RedisModule_ReplyWithStringBuffer(RedisModuleCtx *ctx, const char *buf, size_t len);
int RedisModule_ReplyWithString(RedisModuleCtx *ctx, RedisModuleString *str);
RedisModule_ReplyWithArray(ctx,2);
RedisModule_ReplyWithStringBuffer(ctx,"age",3);
RedisModule_ReplyWithLongLong(ctx,22);
-
RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_LEN);
-
接收参数
- 获取参数类型
int keytype = RedisModule_KeyType(key);
- REDISMODULE_KEYTYPE_EMPTY
- REDISMODULE_KEYTYPE_STRING
- REDISMODULE_KEYTYPE_LIST
- REDISMODULE_KEYTYPE_HASH
- REDISMODULE_KEYTYPE_SET
- REDISMODULE_KEYTYPE_ZSET