Redis 源码之常用数据结构和函数
上一篇 扩展Redis:增加Redis命令 讲了如何动手编写一个命令,但没有具体讲代码的细节,今天讲下Redis代码中的常用数据结构和函数,看完这篇文章希望大家自己能写一个helloworld的命令。
首先讲下环境,代码的版本还是3.2.11的。
一、数据结构
1、robj
robj是Redis源码中用的非常多的数据结构,包括我们输入的命令和参数在服务端都是以robj来表示的。
其中比较重要的是type和ptr字段,type表示数据的类型,常用类型有:
所有客户端输入过来的参数都是STRIGN类型,即我们输入命令:
set key value
则服务端会生成3个robj对象,每个的type都是 OBJ_STRING。
可以参考typeCommand的代码:
还有一个重要的字段是ptr,这是一个void类型,即可以代表任何类型,如果是type为OBJ_STRING,则ptr是一个char*的指针。
另外就是encoding字段了,上面发现所有基本类型是字符串,如果要表示整型怎么办呢,就是通过encoding帮忙了,可以看下代码:
2、client
client结构代表一个连接,当然一个从Redis也是一个连接,所以这个结构有从的一些信息:
整个结构体字段比较多,重点关注以下几块:
argc:参数个数
argv:具体一个个的参数
db:当前选择的数据库
argv[0]表示我们的命令,后面就是命令具体的参数了,如果我们输入命令:
set name ljh
则:
c->argv[0]表示set命令,type为OBJ_STRING,ptr是一个char*;
c->argv[1]表示参数name,type为OBJ_STRING,ptr是一个char*;
c->argv[2]表示参数ljh,type为OBJ_STRING,ptr是一个char*;
通过解析c->argv参数,我们就可以得到一个个的参数进行验证和处理了。
二、常用函数
1、addReplyError
一般表示执行遇到错误,返回客户端一个错误;
这个函数有2个参数,第一个是一个client的指针,第二个为错误字符串:
2、addReply
向输出缓存区增加内容;
有2个参数,第一个也是一个client的指针,第二个是一个robj的指针:
上面是上一篇扩展命令里的代码,如果O的type为OBJ_STRIGN,并且encoding是OBJ_ENCODING_INT,值为5,这里表示向客户端输出以下内容:
:5\r\n
这里讲下Redis协议,响应这块的协议如下:
状态回复(status reply)的第一个字节是 “+”
错误回复(error reply)的第一个字节是 “-“
整数回复(integer reply)的第一个字节是 “:”
批量回复(bulk reply)的第一个字节是 “$”
多条批量回复(multi bulk reply)的第一个字节是 “*”
因为我们的incexpire返回一个整型数字,所以先是:,然后是数字,最后是表示结束的换行和回车。
3、lookupKey
相关的还有lookupKeyRead,lookupKeyWrite,这几个函数都是表示从某个库里查找相应的key,带写的函数会先判断是否过期;
第一个是redisDb结构,第二个是一个robj*,表示要查找哪个key;
当前连接的数据库可以通过 c->db来获取。
4、createStringObjectFromLongLong
这些是创建相应类型robj的命令,有的时候我们要根据一些处理结果返回字符串或数值给客户端,前面讲了大部分函数都接受robj作为参数,像添加内容到输入缓存区的addReply;
其它的命令有:
createStringObject:根据字符串创建robj
createStringObjectFromLongDouble:根据double创建robj
三、调试
大家看完上面代码想自己写个命令呢,按上面讲的基本上可以把环境跑起来,最后就是调试了,可以下个gdb,然后在相应的函数上打断点就可以了,常用命令如下:
break 函数名
print 变量名
上面两个命令应该是最常用的了,第一个是下断点,第二个是打印变量的值。
版权声明: 本文为 InfoQ 作者【心平气和】的原创文章。
原文链接:【http://xie.infoq.cn/article/eae67a147fd3d0daa5200b8bd】。文章转载请联系作者。
评论