Redis在传输层,使用的是TCP协议,每当有客户端连接到服务器的时候,都会创建一个Socket连接,对应一个套接字文件描述符fd。
而在Redis服务器中,是如何维护这些网络连接的呢,接下来我们就来看看。
1、客户端信息
当客户端与Redis服务器连接之后,redisServer结构中会存储一个客户端的链表,该链表节点用来记录与客户端通信的各种信息:
我们重点来关注redisClient以下信息:
int fd
:文件描述符,-1代表伪客户端;robj * name
:客户端名字;int flags
:客户端标志,flags可以是单个标志,或者多个标志的二进制或,常见的标志:- REDIS_LUA_CLIENT:表示客户端是用于处理Lua脚本的伪户端;
- REDIS_MONITOR:客户端正在执行MONITOR命令;
- REDIS_UNIX_SOCKET:服务器使用UNIX套接字来连接客户端;
- REDIS_BLOCKED:客户端正在被BRPOP、BLPOP等命令阻塞;
- REDIS_UNBOKCKED:表示客户端已从阻塞状态中脱离出来,该标志只能在REDIS_BLOCKED标志已经打开的情况下使用;
- REDIS_MULTI:客户端正在执行事务
- REDIS_FORCE_AOF:强制将执行的命令写入到AOF文件里面,一般情况,Redis只会对数据库进行了修改的命令写入到AOF文件中,而对于PUBSUB和SCRIPT LOAD命令,则需要通过该标志,强制将这个命令写入到AOF文件中,另外,为了让主从服务器可以正确载入SCRIPT LOAD命令指定的脚本,需要使用REDIS_FORCE_REPL标志,强制将SCRIPT LOAD命令复制给所有从服务器;
sds querybuf
:客户端输入缓冲区,命令请求字符串,最大大小不能超过1G,否则客户端将被服务器关闭;robj **argv
:要执行的命令,以及所有参赛构成的数组;int argc
:argv数组的长度;struct redisCommand *cmd
:客户端请求对应的命令,从字典结构的命令表中查找得到;char buf[REDIS_REPLY_CHUNK_BYTES]
:固定大小缓冲区,REDIS_REPLY_CHUNK_BYTES值默认为16KB;int bufpos
:固定大小缓冲区易用字节数量;list *reply
:可变大小缓冲区由链表组成,每个节点为一个字符串对象;int authenticated
:客户端身份验证状态,1表示验证通过,如果Redis启用了身份验证功能,则需要用到该字段;time_t ctime
:客户端连接创建时间;time_t lastinteraction
:客户端与服务器最后一次通信时间;time_t obuf_soft_limit_reached_time
:输出缓冲区第一次达到软性限制的时间;
2、命令执行流程
一个命令执行的完整流程如下图所示:
可以发现,Redis执行命令的整个过程,相关的中间信息都存储在redisClient中。
而整个执行过程中,线程模型是怎样的,我们在后面小节会详细介绍。