Author:赵志乾
Date:2018-12-02
Declaration:All Right Reserved!!!
1、Redis客户端与服务器关系维护
Redis客户端同服务器的关系是多对一的关系,即一个Redis服务器可以通过网络连接为多个客户端服务。在《客户端目标数据库切换》中,提到Redis服务器状态信息由redisServer维护,客户端信息由client维护,而对于两者之间的关联关系其实是由redisServer中的clients字段来维护。redisServer.clients字段是一个指向list链表的指针,所有连接到该服务器的Redis客户端均由该链表存储,结构如下:
2、Redis客户端信息
Redis客户端信息由client结构来维护,并且通过链表clients关联到Redis服务器的状态信息中。在client结构有许多字段,我们这次只关注其中一些通用的字段信息。
2.1套接字描述符
client结构中的fd属性为整数类型,用于表征该客户端同服务器端通信所使用的套接字描述符。该字段有一个特殊的值,即-1,当fd为-1时,表示该客户端为伪客户端。伪客户端的含义是指该客户端并非通过网络套接字连接于Redis服务器,而伪客户端的场景主要包括:AOF文件载入还原数据库以及通过lua脚本执行Redis命令。
注:如果一个Redis客户端非伪客户端,我们就将其称为普通客户端,普通客户端的fd均大于-1。如果要查询客户端的fd信息,可以通过指令 client list 进行查询,该指令会遍历reidsServer中的clients链表,这个打印出各客户端的基本信息。见下图:
2.2名称
默认情况下,客户端是没有名称的。我们可以通过指令client setname来为客户端设定一个有意的名称。如下图:
客户端名称对应于client结构中的name字段,默认情况下,客户端名称为空,此时name的值为NULL。当使用client setname为客户端指定名称后,name字段将指向SDS类型的字符串。结构如下图:
2.3输入缓冲区
客户端输入缓冲区用于保存客户端发送的命令请求。使用client中的querybuf来表征,该字段的类型为sds(简单动态字符串)。sds作为Redis自己封装的一个自动扩展的动态字符串,其会根据输入的内容动态的扩展和缩小且使用qb_pos指示当前已经读取到的位置。但其大小不能超过1GB,否则服务器会强行关闭客户端。其对应的内存结构如下:
2.4输出缓冲区
客户端的输出缓冲区用于保存命令执行的回复信息。在client结构中,有两个缓冲区共同组成输出缓冲区。其中一个为buf,其长度固定,默认情况下为16KB,且使用属性bufpos来指示当前已使用的字节数。另一个为reply,其类型为一个指向list的指针。list的每个节点为一个字符串对象,从而可以应对超长字符串的场景。其结构如下:
参考资料:
《Redis设计与实现》---黄健宏
2018-12-01 非稳定版本Redis源码