前言
最近研究下redis源码,现在从最基本的命令行操作来分析,redis是如何处理命令操作的
- redis的set命令操作
我们在redis-cli执行下面的命令
java;gutter:true;
set c c</p>
<pre><code>
debug 发现 t_string.c ,执行了 **void setCommand(client *c)**
其中 client 的定义,client 有非常多的参数,现在我们比较关心的是 querybuf 参数
</code></pre>
<p>typedef struct client { ....</p>
<pre><code>
</code></pre>
<p>sds querybuf; /<em> 请求参数 </em>/</p>
<pre><code>
</code></pre>
<p>} redisClient;</p>
<pre><code>
![redis分析系列之set命令](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20230605/2716747-20220128100252591-1206924256.png)
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**
![redis分析系列之set命令](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20230605/2716747-20220128101139809-1424652453.png)
继续debug ,发现 key 和value 都会保存成 robj对象,
robj 定义
</code></pre>
<p>typedef struct redisObject {</p>
<pre><code>// 类型 (包含 字符串,int 等等)
unsigned type: 4;
// 编码
unsigned encoding: 4;
int refcount;
void *ptr;//字符串地址(通过不同的类型,保存了不同的指针对象)
</code></pre>
<p>} robj;
验证下,是不是我们刚才提交的 set c c ,其中 key 是 c value 也是 c
打印一下,果然是我们输入的参数,
继续 debug,先 lookupKeyWrite 查找key是否存在,然后 setKey 写入redis的hashtable中,最后发送通知,写入回复 reply
总结
- set 命令是在 t_string.c 文件的 setCommand函数处理的
- key和value 会包装成 robj 对象
- 判断是否有过期时间,有的话,会处理 expire ,其中 setExpire 会处理过期时间
- setKey函数会写入redis的hashtable中
- 调用 notifyKeyspaceEvent 事件通知
- 调用 addReply方法,写入回复到客户端
Original: https://www.cnblogs.com/tomj2ee/p/15852427.html
Author: tomj2ee
Title: redis分析系列之set命令
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/570900/
转载文章受原作者版权保护。转载请注明原作者出处!