总述
redis 会为每一个连接的客户端建立一个客户端信息。主要包括以下信息:
-
配置类信息:
- 客户端的ip,端口
- 套接字 描述符
- 客户端的name
- 客户端的flags(客户端的角色,当前所属的状态,例如是master,slave,是否在监听,是否在watch等)
- 最后一次通信时间
-
功能类信息:
- 输入,输出缓冲区等
- 当前指向的数据库
所有的客户端信息已链表的信息保证在redisServer结构体中
结构定义和字段类型说明
typedef struct redisClient {
...
redisDb *db;//当前使用的数据库
int fd;//注意伪客户端(加载aof文件的)的值为-1
string_object * name ;//名称
int flags;//角色集合
sds querybuf;//输入缓冲
str_object **argv; //参数数组,argv[0]是命令 后面分布是参数
int argc; //参数个数
struct redisCommand *cmd;//当前命令的处理函数指针
char buf[REDIS_REPLY_CHUNK_BYTES];//固定输出缓冲区大小,存在较短回复的内容
int bufPos;//固定输出缓冲区的已使用量
list *reply ;//由sds 组成的可变输出缓冲区
int authenticated;//是否通过验证
time_t ctime; //创建时间
time_t lastinteraction; // 最后一次互动时间
time_t obuf_soft_limit_reached_time;//
...
}
flags
定义在redis.h
- 是主服务器还是从服务器
- redis 是否是低于2.8的版本
- redis 是否是伪客户端
- redis_monitor: 是否处于monitor状态
- redis_blocked: 是否被阻塞命令所阻塞
- redis_unblocked: 只能在redis_blocked下使用,表明解除阻塞(不太理解)
- redis_multi: 是否处于事务状态
- redis_dirty_cas,redis_dirty_exec:都是在事务状态下可以设置,表明事务已经失败
- redis_close_asap: 客户端的输出缓冲区大于redis规定的最大值,此时redis 会情况缓冲区,并注销客户端
- 其它。。
tips
只读命令(不会对redis的数据库状态做任何变动)不会发送到从服务器。
但是publish 和 script load 虽然看起来像只读,但是publish存在向所有订阅者发送消息,从而改变客户端状态的副作用,所以也会发送的从服务器
输入缓冲和命令参数和处理命令指针
redis会将接收到的命令存放到querybuf中,
随后对命令进行解析,得出命令参数以及长度。存入argv,argc。
由于是单线程(eventloop),所以同一时间只会有一组客户端参数被保存。
解析完后,通过第一个参数,查找命令对照表,找出对应命令的redisCommand结构体信息(该结构体包含命令的参数个数,执行函数等),同时将指针赋值给redisClient->cmd
命令
CLIENT listCLIENT setname