以往我们想给 Redis 加个功能或类似事务的东西只能用 Lua 脚本,这个东西没有实现真正的原子性,另外也无法使用底层的 API ,实质上比单纯的命令脚本提升有限。

Redis 4.0 终于加入了模块,暴露了必要的 API,并且有自动内存管理(大大减轻编写负担),基于 C99(C++ 或者其它语言的 C 绑定接口当然也可以)。

这东西有多灵活呢?不知道作者是不是为了突出这一点,直接编写了一个神经网络模块。

注意:

redis对布隆过滤器的支持就是通过第三方module来实现的,安装,使用都很简单

可以参考笔者的这篇博客:https://blog.csdn.net/yzf279533105/article/details/110873427

模块 Module 可以动态的载入和卸载,可以实现底层的数据结构也可以调用高层的指令,这一切都只需要包含头文件 redismodule.h ,和 Redis 本身一样简洁优雅。

基本入门

Hello World

// redis 4.0 以上源码可以找到头文件
#include "redismodule.h"
#include <stdlib.h>int HelloworldRand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {RedisModule_ReplyWithLongLong(ctx,rand());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.rand",HelloworldRand_RedisCommand) == REDISMODULE_ERR)return REDISMODULE_ERR;return REDISMODULE_OK;
}

编译命令

g++ -fPIC -c mycal.cpp -o mycal.xo
ld -o mycal.so mycal.xo -shared -lc

一般我更喜欢用 cmake,管理起来更容易

cmake_minimum_required(VERSION 2.8.11)
project(mycal)set(mycal mycal.so)add_library(${mycal} SHARED mycal.cpp)
set_target_properties(${mycal} PROPERTIES PREFIX "" SUFFIX "")  

加载命令

MODULE LOAD /path/to/mymodule.so   # 在 redis-cli 中执行,注意这里 mymodule.so 是文件名

执行命令

helloworld.rand   # 在 redis-cli 中执行

基础 API 一览

#include "redismodule.h" // 这个头文件在 > 4.0 的redis 源代码可以找到
#include <stdlib.h>// redis API 和 argv 参数 都是 RedisModuleString 类型的
int HelloworldRand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {// 自动内存管理// 不需要 close keys/ free replies / free RedisModuleString// 注意为了及时处理内存,使用大内存应该手动 free (用redis对应函数)RedisModule_AutoMemory(ctx);// 错误调用可以使得 redis 直接崩溃,需要检查参数if (argc != 3) return RedisModule_WrongArity(ctx);// 从 redis 字符串获取数据const char *s = RedisModule_StringPtrLen(argv[0], NULL);// 字符串到数字long long myval;if (RedisModule_StringToLongLong(argv[1],&myval) == REDISMODULE_OK) {/* Do something with 'myval' */}// 数字到字符串RedisModuleString *mystr = RedisModule_CreateStringFromLongLong(ctx, 10);// 使用如下的函数而不是 malloc(对Redis透明,无法控制),保证和 redis 的内存分配器一致,默认是 jemalloc// void *RedisModule_Alloc(size_t bytes);// void* RedisModule_Realloc(void *ptr, size_t bytes);// void RedisModule_Free(void *ptr);// void RedisModule_Calloc(size_t nmemb, size_t size);// char *RedisModule_Strdup(const char *str);// 操作 Redis 原生类型底层API,通常是 RedisModule_TypeOperation 的格式命名函数RedisModuleKey *key;key = (RedisModuleKey*)RedisModule_OpenKey(ctx,argv[1],REDISMODULE_WRITE);if (RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_EMPTY) {RedisModule_StringSet(key,argv[2]);}// 高层 API 用 RedisModule_CallRedisModuleCallReply *reply;// sc 是格式化标志位,表示命令的多个参数各是什么类型,s 代表 argv[1] 是一个 RedisModuleString// c 代表 “10” 是以 \0 结尾的 C 字符串reply = RedisModule_Call(ctx,"INCR","sc",argv[1],"10");if (RedisModule_CallReplyType(reply) == REDISMODULE_REPLY_INTEGER) {long long myval = RedisModule_CallReplyInteger(reply);/* Do something with myval. */}// 返回一个数值给调用者RedisModule_ReplyWithLongLong(ctx, rand());return REDISMODULE_OK;
}// 必须的函数
extern "C" int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {// 模块的名称在这里注册,可以跟编译后 so 名字不一样,推荐一样// RedisModule_Init 必须在调用其它API前最先被调用if (RedisModule_Init(ctx, "mycal", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)return REDISMODULE_ERR;// 与其它模块命名冲突会导致命令注册失败,推荐采用 模块名.命令名 方式if (RedisModule_CreateCommand(ctx, "mycal", HelloworldRand_RedisCommand, "write", 1,1,1) == REDISMODULE_ERR)return REDISMODULE_ERR;
}

模块必须的函数只有 RedisModule_OnLoad,它是 redis 调用模块的入口函数。

上面的语言是 C++ ,为了编译成动态时函数的可见性加了 extern "C" 前缀。

用 C 语言开发是最简单的,但事实上任何语言都可以开发 Redis 模块。

在配置文件 redis.conf

增加: loadmoudule /path/module.so [argv0] [argv1] # 配置文件,后面可以加参数,这种方式需要重启redis

客户端工具 redis-cli

module load /path/module.so [argv0] [argv1] # 客户端指令,加载模块,不需要重启redis,但是如果redis关闭后这个module需要重新加载

module list # 列出所有模块

module unload module # 卸载模块,模块名是函数中注册的名称,不是文件名

API

大致可以分为三类:直接操作底层数据;redis 命令操作;内存分配、集群支持等

注意

模块如果有没有捕获或内存泄露出错等问题 Redis 本身是无法处理的,会导致程序整个挂掉,甚至很可能连日志都没有需要非常小心。

参考文献

  1. 开发简介 Redis Modules: an introduction to the API
  2. API 简介 Modules API reference - Redis
  3. 寻找灵感 Redis Labs Modules

redis module模块简单使用相关推荐

  1. Redis Module 模块组件

    介绍 首先介绍下RedisMod这个东西,它是一系列Redis的增强模块.有了RedisMod的支持,Redis的功能将变得非常强大.目前RedisMod中大体包含了如下增强模块: RediSearc ...

  2. 有一万种能力的 Redis Module 初体验

    Redis Module 通过使用外部模块和自定义的 Redis 命令来扩展 Redis 的能力,在 Redis 4.0 版本引入. Reids Module 是一种动态库,可以在启动时通过配置文件或 ...

  3. 简单实例讲解linux的module模块编译步骤

    简单实例讲解linux的module模块编译步骤 (2014-10-24 10:19:17) 标签: module linux 分类:Linux/Unix 本文将直接了当的带你进入linux的模块编译 ...

  4. Android 驱动(8)---简单实例讲解linux的module模块编译步骤

    简单实例讲解linux的module模块编译步骤 原博文地址http://blog.sina.com.cn/s/blog_4ba5b45e0102v25h.html ----------------- ...

  5. 【ES6】Module模块详解

    [ES6]Module模块详解 一.Module的由来 二.严格模式 三.export命令 四.import命令 查看更多ES6教学文章: 参考文献 引言:由于两个JS文件之间相互使用必须通过一个ht ...

  6. 指定module_一个缺失已久的特性 — module模块

    在ES6之前,Javascript还不支持原生的模块化.如果要实现模块化,我们要借助一些框架,比如:requireJS或者seaJS等:什么?没用过也没听过这些框架?没关系,它们不是我们今天要讲的重点 ...

  7. 第二十节:一个缺失已久的特性 — module模块

    在ES6之前,Javascript还不支持原生的模块化.如果要实现模块化,我们要借助一些框架,比如:requireJS或者seaJS等:什么?没用过也没听过这些框架?没关系,它们不是我们今天要讲的重点 ...

  8. 5.Module模块

    (1).模块化的初衷 现在的web系统越来越庞大.复杂,需要团队分工,多人协作,大型系统的javascript文件经常存在复杂的依赖关系,后期的维护成本会越来越高. JavaScript模块化正式为了 ...

  9. amaze ui各个模块简单说明

    amaze ui各个模块简单说明 导航添加依据 http://amazeui.org/css/  下面内容属学习笔记,如有理解偏差和错误请留言相告,感谢!* =(官网这块写的很详细) 一.基本样式 1 ...

最新文章

  1. 华为诺亚方舟开源预训练模型“哪吒”,4项任务均达到SOTA
  2. android悬浮动态权限,android应用内悬浮窗-自动贴边,不需要权限!
  3. python实例(一)
  4. VTK:PolyData之PointSampler
  5. 分类数据的分析-卡方检验运用
  6. SAP Hybris Commerce product读取的调试截图
  7. js能否打印服务器端文档,js打印远程服务器文件
  8. 好象现在才开始热爱生活了
  9. 都安排上了!春晚主持阵容、春晚直播平台、春晚餐桌C位
  10. BZOJ4868: [Shoi2017]期末考试
  11. 深入浅出Mysql 读书笔记
  12. 学校面试计算机老师试题及答案,计算机面试问题及答案 (共2篇).doc
  13. 机械臂速成小指南(五):末端执行器
  14. tf.expand_dims - 增加维度
  15. GBase 8a集群运行报错BLK_TEMP: return NULL in alloc
  16. mysql 汉字笔画排序规则_SQL Server与MySQL中排序规则与字符集相关知识的一点总结...
  17. OD使用经验【转载】
  18. 程序员面试 算法研究 编程艺术 红黑树 机器学习5大系列集锦
  19. 各类型PPT免费模板,无需编辑直接套用即可!
  20. FCoin商业模式不可持续?开始转向“币改”?

热门文章

  1. SQL基本语句语法释义
  2. JAVA/JSP学习系列之Resin+Apache安装
  3. 联想B450系列安装XP且开启AHCI
  4. RHEL4- DNS服务(六)构建DNS缓存服务器
  5. POJ - 1459 Power Network(网络流-最大流)
  6. 中石油训练赛 - 腿部挂件(可持久化字典树)
  7. CodeForces - 1092F Tree with Maximum Cost(树形dp+树根转移)
  8. 特征值与特征向量_机器学习和线性代数 - 特征值和特征向量
  9. mapreduce mysql_MapReduce直接连接MySQL获取数据
  10. 乘积的C语言,c语言矩阵相乘