redis module模块简单使用
以往我们想给 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 本身是无法处理的,会导致程序整个挂掉,甚至很可能连日志都没有需要非常小心。
参考文献
- 开发简介 Redis Modules: an introduction to the API
- API 简介 Modules API reference - Redis
- 寻找灵感 Redis Labs Modules
redis module模块简单使用相关推荐
- Redis Module 模块组件
介绍 首先介绍下RedisMod这个东西,它是一系列Redis的增强模块.有了RedisMod的支持,Redis的功能将变得非常强大.目前RedisMod中大体包含了如下增强模块: RediSearc ...
- 有一万种能力的 Redis Module 初体验
Redis Module 通过使用外部模块和自定义的 Redis 命令来扩展 Redis 的能力,在 Redis 4.0 版本引入. Reids Module 是一种动态库,可以在启动时通过配置文件或 ...
- 简单实例讲解linux的module模块编译步骤
简单实例讲解linux的module模块编译步骤 (2014-10-24 10:19:17) 标签: module linux 分类:Linux/Unix 本文将直接了当的带你进入linux的模块编译 ...
- Android 驱动(8)---简单实例讲解linux的module模块编译步骤
简单实例讲解linux的module模块编译步骤 原博文地址http://blog.sina.com.cn/s/blog_4ba5b45e0102v25h.html ----------------- ...
- 【ES6】Module模块详解
[ES6]Module模块详解 一.Module的由来 二.严格模式 三.export命令 四.import命令 查看更多ES6教学文章: 参考文献 引言:由于两个JS文件之间相互使用必须通过一个ht ...
- 指定module_一个缺失已久的特性 — module模块
在ES6之前,Javascript还不支持原生的模块化.如果要实现模块化,我们要借助一些框架,比如:requireJS或者seaJS等:什么?没用过也没听过这些框架?没关系,它们不是我们今天要讲的重点 ...
- 第二十节:一个缺失已久的特性 — module模块
在ES6之前,Javascript还不支持原生的模块化.如果要实现模块化,我们要借助一些框架,比如:requireJS或者seaJS等:什么?没用过也没听过这些框架?没关系,它们不是我们今天要讲的重点 ...
- 5.Module模块
(1).模块化的初衷 现在的web系统越来越庞大.复杂,需要团队分工,多人协作,大型系统的javascript文件经常存在复杂的依赖关系,后期的维护成本会越来越高. JavaScript模块化正式为了 ...
- amaze ui各个模块简单说明
amaze ui各个模块简单说明 导航添加依据 http://amazeui.org/css/ 下面内容属学习笔记,如有理解偏差和错误请留言相告,感谢!* =(官网这块写的很详细) 一.基本样式 1 ...
最新文章
- 华为诺亚方舟开源预训练模型“哪吒”,4项任务均达到SOTA
- android悬浮动态权限,android应用内悬浮窗-自动贴边,不需要权限!
- python实例(一)
- VTK:PolyData之PointSampler
- 分类数据的分析-卡方检验运用
- SAP Hybris Commerce product读取的调试截图
- js能否打印服务器端文档,js打印远程服务器文件
- 好象现在才开始热爱生活了
- 都安排上了!春晚主持阵容、春晚直播平台、春晚餐桌C位
- BZOJ4868: [Shoi2017]期末考试
- 深入浅出Mysql 读书笔记
- 学校面试计算机老师试题及答案,计算机面试问题及答案 (共2篇).doc
- 机械臂速成小指南(五):末端执行器
- tf.expand_dims - 增加维度
- GBase 8a集群运行报错BLK_TEMP: return NULL in alloc
- mysql 汉字笔画排序规则_SQL Server与MySQL中排序规则与字符集相关知识的一点总结...
- OD使用经验【转载】
- 程序员面试 算法研究 编程艺术 红黑树 机器学习5大系列集锦
- 各类型PPT免费模板,无需编辑直接套用即可!
- FCoin商业模式不可持续?开始转向“币改”?
热门文章
- SQL基本语句语法释义
- JAVA/JSP学习系列之Resin+Apache安装
- 联想B450系列安装XP且开启AHCI
- RHEL4- DNS服务(六)构建DNS缓存服务器
- POJ - 1459 Power Network(网络流-最大流)
- 中石油训练赛 - 腿部挂件(可持久化字典树)
- CodeForces - 1092F Tree with Maximum Cost(树形dp+树根转移)
- 特征值与特征向量_机器学习和线性代数 - 特征值和特征向量
- mapreduce mysql_MapReduce直接连接MySQL获取数据
- 乘积的C语言,c语言矩阵相乘