Table of Contents generated with DocToc
Redis服务器为客户端建立了相应的redis.h/redisClient结构,保存了客户端的当前信息,以及执行相关功能需要的数据结构:
- 客户端的套接字描述符
- 客户端的名字
- 客户端的标志值(flag)
- 客户端正在使用的数据库的指针及号码
- 客户端当前要执行的命令、参数
- 客户端的输入输出缓冲区
- 客户端的复制状态信息
- 客户端的事务状态
- 客户端执行发布与订阅功能用到的数据结构
- 客户端的身份验证标识
- 客户端的统计信息,如创建时间、最后一次通行时间、缓冲区大小超出限制的时间
redisServer
结构保存了一个clients
链表,保存了所有连接的客户端的状态信息。
struct redisServer {
// ...
list *clients;
redisClient *lua_client; // Lua伪客户端,服务器运行时一直存在
// ...
}
typedef struct redisClient {
/*
fd记录客户端正在使用的套接字描述符
伪客户端的fd为-1,不需要套接字连接,目前用于 1. AOF还原, 2. 执行Lua脚本的Redis命令
普通客户端为大于-1的整数。CLIENT list命令可以查看当前正在使用的套接字描述符
*/
int fd;
// 连接到服务器的客户端默认没有名字,CLIENT setname可以设置一个名字。
robj *name;
/*
flags记录了客户端的role,以及目前所处的状态
所以,flags可以是多个二进制或,所有标志在redis.h中定义
*/
int flags;
// 输入缓冲区用于保存客户端发送的命令请求
sds querybuf;
// 解析querybuf的请求,得出命令参数及命令个数
// argv是个数组,每个元素都是一个字符串对象,其中argv[0]是要执行的命令
robj **argv;
int argc;
// redisCommand保存了命令的实现函数,标识、参数个数、总执行次数等统计信息
struct redisCommand *cmd;
// 输出缓冲区保存命令的回复,其中
// 1. buf是固定缓冲区,用于保存长度较小的回复
// 2. reply可变缓冲区,保存长度较大的回复
char bug[REDIS_REPLY_CHUNK_BYTES];
int bufpos;
list *reply;
// 记录客户端是否通过了验证
int authenticated;
time_t ctime;
time lastinteraction;
time_t obuf_soft_limit_reached_time;
// ...
} redisClient;
客户端使用connect函数连接到服务器,服务器就会调用连接事件处理器,为客户端创建相应的客户端状态,并添加到链表的末尾。
一个普通客户端可因为多种原因关闭:
-
客户端进程被杀死
-
发送的协议不符合格式
-
客户端成了
CLIENT KILL
命令的目标 -
服务器配置了timeout选项,客户端空转被断开
-
超出输入/输出缓冲区限制
输出缓冲区的限制包括:硬性限制、弱性限制。超过软性限制一段时间,客户端也会被关闭。
上一章:12、事件
下一章:14、服务器