码迷,mamicode.com
首页 > Web开发 > 详细

Redis学习之外部扩展模块详解

时间:2017-08-22 22:04:28      阅读:395      评论:0      收藏:0      [点我收藏+]

标签:

Redis从4.0版本开始加入了对外部扩展模块的支持。外部扩展模块可以实现新的Redis命令,新的Redis数据结构,总之基本上可以做到所有Redis内核可以做的事情。本文和大家分享的就是redis外部扩展模块相关内容,一起来看看吧,希望对待学习redis有所帮助。 
我个人认为这是迄今为止,Redis最重要的一个改进。友好的API、完善的文档和健壮的基础结构,会快速吸引大量的第三方开发者不断贡献新的内容,Redis的用途必然会更加广泛,用户群也会随之扩大。 
模块的实现 
Redis模块需要引入 redismodule.h ,用C、C++或其他提供C binding的开发语言实现,并编译成动态库 .so 文件。基于 redismodule.h 提供的API实现的模块,在API不变的情况下(API版本号相同),可以兼容不同Redis版本而不需要重新编译。 
在开发模块的时候并不需要依赖Redis的源代码或开发库,只需要把 redismodule.h 拷贝到工程下边引用,实现并导出方法 RedisModule_OnLoad 即可。 
模块可以做什么 
访问Redis数据空间 
Redis提供了两套数据访问的API,一套是较高层的,类似于Lua脚本的API,往往用来调用API没有提供支持的Redis命令。另一套是底层API,速度很快,基本和Redis原生命令一样快,也提供了一些对各种数据结构的进行处理的函数,是推荐的数据访问方式。 
高层API使用 RedisModule_Call 调用Redis命令,如: 
RedisModuleCallReply *reply;reply = RedisModule_Call(ctx,"INCR","sc",argv[1],"10"); 
底层API使用 RedisModule_OpenKey 打开并获取Key指针继而进行后续处理,如: 
RedisModuleKey *key;key = RedisModule_OpenKey(ctx,"somekey",REDISMODULE_READ); 
实现新的数据结构 
对于简单的数据结构,可以使用DMA(direct memory access)将结构编码保存到Redis的String类型中,如: 
// 获取字符串内存指针继而修改其内容 
size_t len; 
char *myptr = RedisModule_StringDMA(key,&len,REDISMODULE_WRITE); 
// 增大,减少或创建字符串 
RedisModule_StringTruncate(key,1024); 
也可以使用API注册并实现新的数据结构,可以控制内存的分配与释放,RDB序列化,AOF重写等。 这里 是Redis官方的一个例子,好奇的同学可以自己点进去看看。 
实现阻塞命令 
阻塞命令(Blocking commands)会阻塞客户端,直到某个期望的事件发生才会返回,比如List的 BLPOP 命令。模块API也提供了实现阻塞命令的功能,在写这篇文章的时候,Blocking Command的相关API还处于试验阶段,其设计还没有最终确定,所以这里就不详细说明了,以后再将这部分补全。 
加载模块 
模块有两种加载方式,一是在配置文件 redis.conf 中使用 loadmodule /path/to/mymodule.so在Redis启动时加载。另一种方式在运行时使用命令 MODULE LOAD /path/to/mymodule.so 加载。加载的模块可以使用命令 MODULE LIST 查看,使用 MODULE UNLOAD mymodule 卸载。 
在载入的模块的时候可以传入参数,如: loadmodule mymodule.so foo bar 1234 ,参数会被传入模块的 OnLoad 方法中。 
对Redis Cluster的支持 
模块是可以支持Redis Cluster的,但是目前还找不到相关的介绍,只是在官方文档里提到两个相关的API函数: RedisModule_IsKeysPositionRequest(ctx) 与 RedisModule_KeyAtPos(ctx,pos)。于是仔细的看了一下官方API文档中的相关部分,并对照了一下其他模块的实现,猜了一下大概的实现方式。 
首先,在创建Redis模块的命令时,需要调用API方法: 
int RedisModule_CreateCommand(RedisModuleCtx *ctx,const char*name, RedisModuleCmdFunc cmdfunc,const char*strflags,intfirstkey,intlastkey,intkeystep); 
其中的 strflags 参数的一个flag为 getkeys-api ,意思是这个方法是否支持返回参数中key。一个方法接收的参数有多个,但并不是每一个都是key,比如 LRANGE key start stop 中,只有第一个参数是key。而Redis需要知道一个命令涉及到哪些key,才能在集群中找到对应的服务器并执行命令。 
如果一个命令支持 getkeys-api ,那么在集群环境下, RedisModule_IsKeysPositionRequest(ctx) 方法就会返回true,就是说需要方法标出参数中的key,这就用到了 RedisModule_KeyAtPos(ctx,pos) 方法,其中 pos 是参数的位置。下边是 rxzsets 中相关的代码: 
int ZUnionTopKCommand(RedisModuleCtx *ctx, RedisModuleString **argv,intargc){ 
... 
if (RedisModule_IsKeysPositionRequest(ctx)) { 
for (int i = 0; i < numkeys; i++) { 
RedisModule_KeyAtPos(ctx, 3 + i); 
} 
return REDISMODULE_OK; 
} 
... 
} 
int RedisModule_OnLoad(RedisModuleCtx *ctx){ 
... 
if (RedisModule_CreateCommand(ctx, "zuniontop", ZUnionTopKCommand, 
"readonly getkeys-api", 1, 1, 
1) == REDISMODULE_ERR) 
... 
} 
Redis Module Hub 
Redis Module Hub 是Redis官方的模块仓库,目前已经有将近二十个模块,其中一大半是Redis Labs自己贡献的,算是抛砖引玉吧,下边随便拿出几个做一下简单的介绍: 
· 对现有数据结构功能的扩展,如: 
· rxkeys 提供了按正则表达式批量获取与删除条目的功能 
· rxhashes 提供了在Hash中改变现有条目的值并返回原值的原子操做 
· rxlists 提供了7个新的列表操作方法。 
· 新数据结构,如: 
· rejson 提供了对原生JSON格式支持,允许对JSON数据内的值进行获取与修改 
· Redis Graph 添加了对图数据库的支持 
· redisearch 实现了全文搜索,使用特殊的压缩数据结构,加快了搜索的速度,并且减少了内存占用 
· redis-ml 实现了多个机器学习常用的数据结构及相关方法 
· 对功能的扩展,如: 
· graphicsmagick 提供类似GraphicsMagick的图片处理功能,从此生成缩略图,打水印都可以在Redis里做了 
· redablooms 基于RedisString的Bloom filter,可以用于ID生成 
· password 提供加密的密码存储 


来源:千里

Redis学习之外部扩展模块详解

标签:

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
jiangjie190
加入时间:2016-02-19
  关注此人  发短消息
文章分类
jiangjie190”关注的人------(0
jiangjie190”的粉丝们------(0
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!