redis服务器是典型的一对多服务器程序:一个服务器能够与多个客户端创建网络链接,每一个客户端能够向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回redis
复。数组
经过使用由I/O多路复用技术实现的文件事件处理器,redis服务器使用单线程单进程的方式来处理命令请求,并与多个客户端进行网路通讯。安全
对于每一个与服务器进行链接的客户端,服务器都为这些客户端创建了相应的redisClient结构(客户端状态),这个结构保存了客户端当前的状态信息,以及执行相关功能是须要的数据结构,包括客户端的名字,客户端的套接字描述符等。bash
redis服务器状态结构的clients属性是一个链表,这个链表保存了全部与服务器链接的客户端状态结构,对客户端执行批量操做,或者查找某个指定的客户端,均可以经过遍历clients链表来完成。服务器
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_MASTERlua
#客户端正在被列表命令阻塞
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.当建立的是普通客户端时,服务器会为这个客户端建立相应的客户端状态。当网络链接关闭 或 发送了不合协议格式的命令请求 或 成为client_kill命令的目标 或 空转时间超时 或 输出缓冲区大小超过限制,以上这些缘由会致使客户端链接关闭;
2.用于处理lua脚本的伪客户端在服务器初始化时候建立,知道服务器关闭;
3.载入aof文件的伪客户端,知道文件载入完成关闭