5 客户端
结构:redis.h/redisClient,保存了客户端的状态信息以及数据结构
redisServer的clients属性为链表,保存了所有与服务器连接的客户端的状态结构:
5.1 客户端属性
分为两类:通用、特定功能,CLIENT list可以列出目前所有连接到服务器的客户端
接下来介绍通用属性
5.1.1 socket描述符
int fd;//记录了客户端正在使用的socket描述符
根据客户端类型的不同,fd的值可以是-1或大于-1的整数:
5.1.2 名字
一般情况下客户端没名字,使用CLIENT setname可以命名,使客户端的身份或业务更清晰
redisClient.name属性用来保存名字:robj* name;没设置名字则指向null,设了则指向该名字的字符串
5.1.3 标志
redisClient.flags记录了客户端的角色以及客户端目前所处的状态:int flags;
其值可以为:
以下标志记录了客户端的角色:REDIS_MASTER、REDIS_SLAVE、REDIS_PRE_PSYNC、REDIS_LUA_CLIENT
以下标志记录了客户端目前所处的状态:REDIS_MONITOR、REDIS_UNIX_SOCKET、REDIS_BLOCKED、REDIS_UNBLOCKED、REDIS_MULTI、REDIS_DIRTY_CAS、REDIS_CLOSE_ASAP、REDIS_CLOSE_AFTER_REPLY、REDIS_ASKING、REDIS_FORCE_AOF、REDIS_MASTER_FORCE_REPLY
5.1.4 输入缓冲区
redis.Client.querybug用于保存客户端发送的命令请求及其长度:sds querybug;
输入缓冲区大小会根据输入内容动态变化,但是最大不能超过1GB,否则此客户端将被服务器关闭
例子:SET key value
5.1.5 命令与命令参数
argv、argc属性:在服务器将客户端发送的命令请求保存到客户端状态的querybuf属性之后,服务器将对命令请求的内容进行分析,并将得出的命令和命令参数个数分别进行保存:robj **argv;int argc;
agrv是一个数组,元素为字符串对象,第一项为命令,其他项为命令参数;argc是argv数组的长度
例子:SET key value
5.1.6 命令的实现函数
得出argv、argc属性后,服务器使用cmd属性所指向的redisCommand结构,加上argv、argc,在命令表中查找命令所对应的命令实现函数,调用此函数,执行客户端指定的命令
命令表为cmd属性:struct redisCommand *cmd;
在命令表中找到对应的redisCommand结构时,将此指针指向这个结构
redisCommand:键为SDS结构,值为对应的redisCommand结构
保存了命令的实现函数、命令的标志、命令应该给定的参数个数,命令的总执行次数和总消耗时长
例子:argv[0]为SET
5.1.7 输出缓冲区
保存命令回复
有两个输出缓冲区,一个大小固定,一个大小可变,区别在于保存的内容不同
- 固定大小缓冲区
属性:char buf[REDIS_REPLY_CHUNK_BYTES],默认大小为16*1024;int bufpos,记录buf数组目前已使用的字节数量
- 可变大小缓冲区
使用时机:固定大小缓冲区使用完时,或回复太大而固定大小缓冲区放不下
属性:list *reply,用来连接多个字符串对象
理论上可以无限长,实际上为了避免客户端的缓冲区过大,占用过多的服务器资源,服务器会时刻检查客户端的输出缓冲区大小,并在其超出范围时,执行相应的限制:硬性限制、软性限制
client-output-buffer-limit选项可以进行设置:
设置例子:
5.1.8 身份验证
int authenticated:记录客户端是否通过了身份验证
为0则未通过,除了AUTH命令,其他命令会被拒绝执行;为1则通过
此属性需要服务器启用身份验证功能
5.1.9 时间
time_t ctime、time_t lastinteraction、time_t obuf_soft_limit_reached_time
ctime属性记录了创建客户端的时间;可用来计算客户端与服务器已经连接了多少秒,CLIENT list命令的age域记录此秒数
lastinteraction记录了客户端与服务器最后一次互动的时间;可用来计算客户端空转时间,CLIENT list命令的idle域记录此秒数
obuf_soft_limit_reached_time记录了输出缓冲区第一次到达软性限制的时间