客户端属性
客户端状态包含的属性可以分为两类:
一类是比较通用的属性, 这些属性很少与特定功能相关, 无论客户端执行的是什么工作, 它们都要用到这些属性。 另外一类是和特定功能相关的属性, 比如操作数据库时需要用到的 db 属性和 dictid 属性, 执行事务时需要用到的 mstate 属性, 以及执行 WATCH 命令时需要用到的 watched_keys 属性, 等等。 本章将对客户端状态中比较通用的那部分属性进行介绍, 至于那些和特定功能相关的属性, 则会在相应的章节进行介绍
typedef struct redisClient {
// ...
int fd;
// ...
} redisClient;
根据客户端类型的不同, fd 属性的值可以是 -1 或者是大于 -1 的整数:
伪客户端(fake client)的 fd 属性的值为 -1 : 伪客户端处理的命令请求来源于 AOF 文件或者 Lua 脚本, 而不是网络, 所以这种客户端不需要套接字连接, 自然也不需要记录套接字描述符。 目前 Redis 服务器会在两个地方用到伪客户端, 一个用于载入 AOF 文件并还原数据库状态, 而另一个则用于执行 Lua 脚本中包含的 Redis 命令。 普通客户端的 fd 属性的值为大于 -1 的整数: 普通客户端使用套接字来与服务器进行通讯, 所以服务器会用 fd 属性来记录客户端套接字的描述符。 因为合法的套接字描述符不能是 -1 , 所以普通客户端的套接字描述符的值必然是大于 -1 的整数。 执行 CLIENT_LIST 命令可以列出目前所有连接到服务器的普通客户端, 命令输出中的 fd 域显示了服务器连接客户端所使用的套接字描述符:
- addr:地址及端口
- fd:套接字描述符
- name: 可以使用client setname 设置某个链接的名称
- age: 链接的时间,单位秒
- idle:空闲时间,单位秒
- flags:记录了客户端的角色(role)
# 客户端是一个主服务器
REDIS_MASTER
# 客户端正在被列表命令阻塞
REDIS_BLOCKED
# 客户端正在执行事务,但事务的安全性已被破坏
REDIS_MULTI | REDIS_DIRTY_CAS
# 客户端是一个从服务器,并且版本低于 Redis 2.8
REDIS_SLAVE | REDIS_PRE_PSYNC
# 这是专门用于执行 Lua 脚本包含的 Redis 命令的伪客户端
# 它强制服务器将当前执行的命令写入 AOF 文件,并复制给从服务器
REDIS_LUA_CLIENT | REDIS_FORCE_AOF | REDIS_FORCE_REPL
输入缓冲区
typedef struct redisClient{
sds querybuf;
}redisClient
- 输入缓存区的大小会根据输入内容动态的缩小或者扩大,但它的最大大小不能超过1GB,否则服务器将关闭这个客户端。
命令与参数
typedef struct redisClient{
robj **argv;
int argc;
}redisClient
- argv属性是一个数组,数组中的每个项都是一个字符串对象,其中argv[0]是要执行的命令,而之后的其他项则传给命令的参数。
- argc属性则负责记录argv数组的长度
命令的实现函数
举例命令:set key value 直接看图:
输出缓冲区
执行客户端的回复会保存在客户端状态的输出缓冲区里面,每个客户端都有两个输出缓冲区可用,一个缓存区是固定大小,另一个缓冲区的大小是可变的
- 固定大小的缓冲区用于保存那些长度比较小的回复,比如ok、简短的字符串值、整数值、错误回复等等。
- 可变大小的缓冲区用于保存那些长度比较大的回复,比如一个非常长的字符串值,一个由很多项组成的列表,一个包含了很多元素的集合等等。
typedef struct redisClient{
char buf[REDIS_REPLY_CHUNK_BYTES];
int bufpos;
list *reply;
}
- buf数组,REDIS_REPLY_CHUNK_BYTES默认值16*1024,大小为16KB
- bufpos记录buf数组使用字节的数量
- reply是一个链表
固定缓冲区
可变缓冲区身份验证
- authenticated:0未验证,1已验证通过
- requirepass:配置此属性是的打开验证
客户端的创建与关闭
什么时候客服端关闭- 客户端退出或者被杀死
- 客户端发送不符合协议格式的命令,被服务端关闭
- 被 client kill
- 服务器设置了timeout
- 输入缓冲区大于限制大小,默认1GB
- 回复的命令大于输入缓冲区的限制
配置
- clinet-output-buffer-limit normal 0 0 0 :表示不限制客户端的输出缓冲区大小
- clinet-output-buffer-limit slave 256mb 64mb 60 :硬性设置256MB,软性设置为64MB,软性限制的时长60秒
- clinet-output-buffer-limit pubsub 32mb 8mb 60 :发布与订阅硬性限制32MB,软性限制8MB,软性相纸的时长为60秒
伪客户端
- lua脚本
- AOF文件:服务器载入AOF文件时
重点
- 服务器状态结构使用 clients 链表连接起多个客户端状态, 新添加的客户端状态会被放到链表的末尾。
- 客户端状态的 flags 属性使用不同标志来表示客户端的角色, 以及客户端当前所处的状态。
- 输入缓冲区记录了客户端发送的命令请求, 这个缓冲区的大小不能超过 1 GB 。 命令的参数和参数个数会被记录在客户端状态的 argv 和 argc 属性里面, 而 cmd 属性则记录了客户端要执行命令的实现函数。
- 客户端有固定大小缓冲区和可变大小缓冲区两种缓冲区可用, 其中固定大小缓冲区的最大大小为 16 KB , 而可变大小缓冲区的最大大小不能超过服务器设置的硬性限制值。
- 输出缓冲区限制值有两种, 如果输出缓冲区的大小超过了服务器设置的硬性限制, 那么客户端会被立即关闭; 除此之外, 如果客户端在一定时间内, 一直超过服务器设置的软性限制, 那么客户端也会被关闭。
- 当一个客户端通过网络连接连上服务器时, 服务器会为这个客户端创建相应的客户端状态。 网络连接关闭、 发送了不合协议格式的命令请求、 成为 CLIENT_KILL 命令的目标、 空转时间超时、 * * 输出缓冲区的大小超出限制, 以上这些原因都会造成客户端被关闭。 处理 Lua 脚本的伪客户端在服务器初始化时创建, 这个客户端会一直存在, 直到服务器关闭。
- 载入 AOF 文件时使用的伪客户端在载入工作开始时动态创建, 载入工作完毕之后关闭。