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

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 提供加密的密码存储

来源:千里

时间: 2024-10-13 03:13:19

Redis学习之外部扩展模块详解的相关文章

Redis学习笔记4-Redis配置详解

原文:  http://blog.csdn.net/mashangyou/article/details/24555191 在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redis学习笔记中Redis的按照方式按照后,Redis的配置文件是/etc/redis/6379.conf.下面是Redis2.8.9的配置文件各项的中文解释. 1 #daemon

Redis学习之数据类型List详解

本文和大家分享的主要是redis数据类型中的list相关内容,一起来看看吧,希望对大家学习redis有所帮助. list即链表,它是一个能维持数据先后顺序的列表,便于在表的两端追加和删除数据,中间位置的存取具有O(N)的时间复杂度,是一个双向链表. 一.内部原理 redis内部实现代码在quicklist.c(注释:A doubly linked list of ziplists)中,它确实是一个双向链表,并且是一个ziplist双向列表. ziplist是什么? 一个经过特殊编码的的双向链表,

Redis学习之Sort Set详解

本文和大家分享的主要是Redis中Sort Set相关内容,一起来看看吧,希望对大家学习redis有所帮助. 游戏服务器需要做一个排行榜实时更新,如果沿用传统的方法,一般是通过后端的定时任务去跑数据来生成排行榜数据,这种方法一方面无法满足产品对功能实时性的要求,另一方面也一定程度上消耗服务器端有限的资源.如果从每次数据库读取数据并进行排名(使用Mysql的sort关键字进行排序),在关卡数据量的级数大时是一种效率低的方法.在查阅大量资料后,发现了Redis中的有序集合(Sort Set). Re

Redis学习之字符串类型详解

本文和大家分享的主要是Redis中字符串相关内容,一起来看看吧,希望对大家学习redis有所帮助. 字符串类型是最基本的数据类型,能够存储所有的字符串,包括二进制数据 json 化对象, 一个字符串类型的键的数据的最大容量是 512 MB 字符串类型是其他几种类型的基础,如列表类型是以列表的形式组织字符串,集合类型是以集合的形式组织字符串 获得符合规则的键名列表 keys pattern # ? 匹配一个字符 # *  匹配任意一个字符 # [] 匹配括号中的任意一个字符.可以使用 - 表示范围

Redis学习之列表类型详解

本文和大家分享的主要是redis的列表类型相关内容,一起来看看吧,希望对大家学习redis有所帮助. 列表类型,可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段 列表类型内部是使用双向链表实现的,所以向列表两端添加元素的时间复杂度是 o(1),获取越接近两端的元素速度就越快 链表的代价是通过索引访问元素比较慢 向列表两端添加元素 向列表左边添加元素,返回增加后列表的长度 LPUSH key value1 value2 127.0.0.1:6379> LPUS

Shell学习之Bash变量详解(二)

Shell学习之Bash变量详解 目录 Bash变量 Bash变量注意点 用户自定义变量 环境变量 位置参数变量 预定义变量 Bash变量 用户自定义变量:在Bash中由用户定义的变量. 环境变量:这种变量中主要保存和系统操作环境相关的数据. 位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的. 预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的. Bash变量注意点 1.变量名称可以由字母.数字和下划线组成,但是不能以数字

Redis实战和核心原理详解(5)使用Spring Session和Redis解决分布式Session跨域共享问题

Redis实战和核心原理详解(6)使用Spring Session和Redis解决分布式Session跨域共享问题 前言 对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash.轮训.根据权重.随机等.不管对于哪一种负载均衡算法,由于Nginx对不同的请求分发到某一个Tomcat,Tomcat在运行的时候分别是不同的容器里,因此会出现session不同步或者丢失的问题. 实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat.Jetty等服务器提

Linux学习总结之LVM2详解

大纲: 简介 版本 LVM基本术语 LVM模块 具体操作 对添加的硬盘进行分区( fdisk /dev/[hs]d[a-z] ) 对创建的分区创建物理卷(pvcreate) 给逻辑卷创建逻辑容器(卷组) 在卷组创建大小不同的逻辑卷(lvcreate) 给已存在的卷组扩大容量 实现在线扩大LVM容量 实现缩减LVM容量(不支持在线缩减) 减小卷组容量 利用给LVM创建快照,并完成备份并还原 简介: LVM是Logical Volume Manager(逻辑卷管理器)的简写,又译为逻辑卷宗管理器.逻

redis服务部署及配置详解

Redis是一种高级key-value数据库.它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富.有字符串,链表,集合和有序集合.支持在服务器端计算集合的并,交和补集(difference)等,还支持多种排序功能.所以Redis也可以被看成是一个数据结构服务器. Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为"半持久化模式"):也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为"全