tomj2ee

 前言

最近研究下redis源码,现在从最基本的命令行操作来分析,redis是如何处理命令操作的

 

1. redis的set命令操作

我们在redis-cli执行下面的命令

set  c c  

debug 发现 t_string.c ,执行了 void setCommand(client *c) 

 其中 client 的定义,client 有非常多的参数,现在我们比较关心的是 querybuf 参数

 

typedef struct client {   
....
 sds querybuf;           /* 请求参数 */
} redisClient;

 

 

 

2. 命令解析

redis-cli 客户端执行 set c  c  命令后,redis服务会保存到 client的querybuf 字段里面,数据封装成  "*3\r\n$3\r\nset\r\n$1\r\nc\r\n$1\r\nc\r\n"

其中 *3 表示 有3个数据, \r\n 作为分隔符

$3 代表 第一个参数有3个字节数目,就是 set  

$1 代表 第二个参数c 

 

 

3.解析好参数后,最后调用 setGenericCommand

 

 

 继续debug ,发现 key 和value 都会保存成 robj对象,

robj 定义

typedef struct redisObject { 
   
    // 类型 (包含 字符串,int 等等)
    unsigned type: 4;

    // 编码
    unsigned encoding: 4;
    int refcount;
    void *ptr;//字符串地址(通过不同的类型,保存了不同的指针对象)

} robj;

 

 

 

验证下,是不是我们刚才提交的  set c  c ,其中 key 是 c  value  也是 c

打印一下,果然是我们输入的参数,

 

 

 

 继续 debug,先  lookupKeyWrite 查找key是否存在,然后 setKey 写入redis的hashtable中,最后发送通知,写入回复 reply

 

 

 

 

总结

  1.  set 命令是在 t_string.c 文件的 setCommand函数处理的
  2.  key和value 会包装成 robj 对象
  3. 判断是否有过期时间,有的话,会处理 expire ,其中 setExpire 会处理过期时间
  4. setKey函数会写入redis的hashtable中
  5. 调用 notifyKeyspaceEvent 事件通知
  6. 调用 addReply方法,写入回复到客户端

 

相关文章: