一.客户端
redis服务器是典型的一对多服务器程序:一个服务器可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回
复。
通过使用由I/O多路复用技术实现的文件事件处理器,redis服务器使用单线程单进程的方式来处理命令请求,并与多个客户端进行网路通信。
对于每个与服务器进行连接的客户端,服务器都为这些客户端建立了相应的redisClient结构(客户端状态),这个结构保存了客户端当前的状态信息,以及执行相关功能是需要的数据结构,包括客户端的名字,客户端的套接字描述符等。
redis服务器状态结构的clients属性是一个链表,这个链表保存了所有与服务器连接的客户端状态结构,对客户端执行批量操作,或者查找某个指定的客户端,都可以通过遍历clients链表来完成。
1.1 客户端状态的属性:
typedef struct redisClent{ //... int fd; robj *name; int flags; sds querybuf; robj **argv; int argc; struct redisCommand *cmd;
char buf[REDIS_REPLY_CHUNK_BUYTES];
int bufpos;
int authenticated;
time_t ctime;
time_t lastinteraction;
time_t obuf_soft_limit_reached_time; //... }redisClient;
1.套接字描述符 - 客户端状态的fd属性记录了客户端正在使用的套接字描述符
根据客户端类型的不同,fd的值可以是-1或者大于-1的整数:伪客户端的fd=-1,普通客户端的fd大于1
2.名字 - 默认情况下,一个连接到服务器的客户端是没有名字的,不过可以在客户端执行clinet setname命令为客户端设置一个名字
3.标志 - flags属性记录了客户端的角色,以及客户端目前所处的状态,比如:
#客户端是一个主服务器
REDIS_MASTER
#客户端正在被列表命令阻塞
REDIS_BLOCKED
#客户端正在执行事务,但事物的安全性已被破坏
REDIS_MULTI | REDIS_DIRTY_CAS
4.输入缓冲区 - 保存客户端发送的命令请求
5.命令与命令参数 - 服务器对命令请求的内容进行分析,并得出的命令参数和命令参数的个数分别保存到客户端状态的argv和argc属性
6.命令的实现函数 - 根据argv[0]的值,去命令表查找对应的命令实现函数
7.输出缓冲区 - 执行命令所得的命令回复会被保存在客户端状态的输出缓冲区里面,每个客户端都有两个输出缓冲区可用,一个缓冲区的大小是固定的,另一个缓冲区的大小是可变的.
固定大小的缓冲区用于保存那些长度比较小的回复,比如ok,简短的字符串值,整数值,错误回复等。
可变大小的缓冲区用于保存那些长度比较小的回复,比如一个非常长的字符串值,一个由很多项组成的列表,一个包含了很多元素的集合等等。
buf是一个字节数组,而bufpos记录了buf数组目前已使用的字节数量。
REDIS_REPLY_CHUNK_BUYTES常量目前的默认值是16*1024,也就是说buf数组的默认大小为16KB。
8.身份验证 - 用于记录客户端是否通过了身份验证,authenticated=1表示通过验证,authenticated属性仅在服务器启用了身份验证功能使用。
9.时间
ctime记录的是创建客户端的时间
lastinteraction记录了客户端和服务器最后一次进行互动的时间
obuf_soft_limit_reached_time属性记录了输出缓冲区第一次到达软性限制的时间。
1.2 客户端的创建与关闭
1.当创建的是普通客户端时,服务器会为这个客户端创建相应的客户端状态。当网络连接关闭 或 发送了不合协议格式的命令请求 或 成为client_kill命令的目标 或 空转时间超时 或 输出缓冲区大小超过限制,以上这些原因会导致客户端连接关闭;
2.用于处理lua脚本的伪客户端在服务器初始化时候创建,知道服务器关闭;
3.载入aof文件的伪客户端,知道文件载入完成关闭