Redis服务器是一对多服务器程序:一个服务器可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接受并处理客户端发送的命令请求,并向客户端返回命令回复。

创建普通客户端:

服务器调用连接事件处理器,为客户端创建相应的客户端状态,并将这个新的客户端状态添加到服务器状态结构clients末尾

【Redis客户端】客户端_套接字

 

客户端属性:

套接字描述符:fd

fd属性记录了客户端正在使用的套接字描述符

【Redis客户端】客户端_套接字_02

 

(1)fd等于-1,表示是伪客户端,不需要网络连接,不需要套接字连接。Redis服务器会在两个地方用到伪客户端:

载入AOF文件并还原数据库状态;执行Lua脚本中包含的Redis命令

(2)普通客户端fd值大于-1的整数,普通客户端使用套接字与服务器进行通信,所以服务器会用fd属性来记录客户端套接字的描述符。

名字:name

【Redis客户端】客户端_运维_03

 

name是客户端的命中率,指向一个字符串对象

标志:flags

flags记录了客户端的角色和客户端的状态。

【Redis客户端】客户端_套接字_04

 

【Redis客户端】客户端_套接字_05

 

【Redis客户端】客户端_套接字_06

 

输入缓冲区:querybuf

【Redis客户端】客户端_运维_07

 

客户端状态输入缓冲区用于保存客户端发送的命令请求。

输入缓冲区的大小根据输入内容动态缩小或者扩大,但最大不超过1GB。

命令与命令参数:

服务器将客户端发送的命令保存到客户端querybuf属性之后,服务器将对命令请求的内容进行分析,并将得出的命令参数以及命令参数的个数分别保存到客户端的argv和argc属性中。

【Redis客户端】客户端_套接字_08

 

(1)argv属性 是一个数组,数组中的每个项都是一个字符串对象,其中argv[0]是要执行的命令,之后的其他项是传给命令的参数

(2)argc属性 负责记录argv数组的长度

【Redis客户端】客户端_运维_09

 

命令的实现函数:

服务器会根据argv[0]的值,在命令表中查找命令所对应的命令实现函数。

命令表是一个字典,字典的键是SDS结构,保存了命令的名字,字典的值是命令所对应的redisCommand结构,这个结构保存了命令的实现函数,命令的标志,命令应该给定的参数个数,命令的总执行次数和总消耗时长等统计信息。

当程序在命令表中成功找到argv[0]所对应的redisCommand结构时 ,会将客户端状态的cmd指向这个结构。

之后,服务器就可以使用cmd属性指向的redisCommand结构,以及argv,argc属性中保存的命令参数信息,调用命令实现函数,执行客户端指定的命令。

【Redis客户端】客户端_客户端_10

 

【Redis客户端】客户端_网络_11

 

输出缓冲区:

执行命令回复会保存在客户端状态的输出缓冲区里面,每个客户端都有两个输出缓冲区可用。

(1)固定大小的缓冲区用于保存那些长度比较小的回复。由字节数组实现

【Redis客户端】客户端_网络_12

 

(2)可变大小的缓冲区用于保存那些长度比较大的回复。由字符串对象的链表实现,通过链表来连接多个字符串对象,服务器可以为客户端保存一个非常长的命令回复。

【Redis客户端】客户端_网络_13

 

身份验证:

客户端状态的authenticated属性用于记录客户端是否通过了身份验证。

authenticated值为0表示未通过身份验证,值为1表示通过了身份验证。

当客户端authenticated属性的值为0时,除了AUTH命令之外,客户端发送的其他命令都会被服务器拒绝执行。

如果服务器没有启用身份验证的话,那么authenticated属性的值为0(默认值),服务器也不会拒绝执行命令

【Redis客户端】客户端_服务器_14

 

时间:

ctime属性:记录创建客户端的时间,可以用来计算客户端与服务器已经连接了多少秒。

lastinteraction属性:记录客户端与服务器最后一次互动的时间。计算客户端的空转时间