当前位置:   article > 正文

REDIS源码篇(4)——命令执行过程(readQueryFromClient)_redis源码readqueryfromclient

redis源码readqueryfromclient

前面讲过,ae循环在收到客户端请求时,会调用请求处理器——acceptTcpHandler ,而请求处理器会创建新的套接字并监听和绑定命令处理器——readQueryFromClient。本篇着重分析命令的执行过程。

大概可分为:

1、读取并分析套接口中协议格式的命令请求,设置redisClient的queryBuf、argv和argc属性------(processInlineBuffer)

2、执行命令------(processCommand)

  1. 查找对应的命令实现
  2. 执行预备操作
  3. 执行命令及执行完的后续操作

3、将命令回复发送给客户端------(sendReplyToClient)


源码分析:

首先一路跟踪readQueryFromClient函数来到processInputBuffer。这里主要看processInlineBufferprocessCommand分别对应上面的1、2两点
在这里插入图片描述

1、读取并分析套接口中协议格式的命令请求,设置redisClient的argv和argc属性(processInlineBuffer)
在这里插入图片描述
2、执行命令(processCommand)
在这里插入图片描述
上面除了lookupCommand(匹配命令实现函数)外,其他的大都是命令执行前的预备操作,而真正执行命令的地方在call方法

call:
在这里插入图片描述
其中c->cmd->proc©这一行即执行了对应的命令实现函数。后面的则是执行命令的后续操作(但不包括返回给客户端的操作)

3、将命令回复发送给客户端
跟踪完readQueryFromClient会发现并没有看到有回复执行结果给客户端的代码。
那么redis是如何将执行结果回复给客户端的呢?
以set命令为例,点开setCommand可以看到addReply方法
在这里插入图片描述
不点进去看的同学可能会以为这里就是回复了。但其实不然,这里只是将当前客户端加入了server.clients_pending_write,并且将执行结果存到bufpos缓存区而已,并没有真正的回复。。。
代码看到这里,一次事件处理就已经看完了。

但是还是没有回复客户端啊???究竟是如何回复的?
答案在aeMain(redis事件处理循环)
前面讲过,除了将执行结果存到缓存区外,还会将当前客户端加入server.clients_pending_write。而在aeMain每次处理事件之前会先执行beforesleep方法
在这里插入图片描述
而beforeSleep会执行handleClientsWithPendingWrites(处理缓存区里的写数据)
在这里插入图片描述
handleClientsWithPendingWrites方法会先尝试执行writeToClient直接回复。若不行,再执行aeCreateFileEvent创建一个文件写事件并绑定回复处理器sendReplyToClient加入事件循环,由后面的事件循环再调用。
在这里插入图片描述
总的来说回复流程如下:
在这里插入图片描述


时序图分析:

连接请求时序图:
在这里插入图片描述

命令请求时序图:
在这里插入图片描述

命令回复时序图:
在这里插入图片描述

参考文献:《Redis设计与实现》黄健宏著、redis-5.0.14源码

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号