Redis服务器是典型的一对多服务器程序:一个服务器可以和多个客户端建立网络连接,Redis使用单线程单进程的方式来处理命令请求(通过IO多路转接实现),并和多个服务端进行网络通信。

每个和服务端进行连接的客户端,服务端都为这些客户端建立了对应的redisClient结构(保存客户端状态),这个结构保存客户端当前的状态信息。所有的redisClient保存在clients属性中,这个clients是一个链表,如果想查找某个指定的客户端,可以通过遍历clients链表来完成。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

一,客户端属性

分两类:

  比较通用的属性:无论客户端执行的是什么,都要用到这些属性

  特定功能相关的属性:比如:操作数据库时用到的db属性,执行事物时用到的mstate属性,

1.套接字描述符: int fd

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

typedef struct redisClient{

  int fd;

}

伪客户端的fd属性值为-1,比如AOF文件或Lua脚本,这种客户端不需要套接字连接

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

2.名字

默认情况下,一个连接到服务器的客户端是没有名字的。

typedef struct redisClient{

  robj *name;

}

如果客户端没有为自己设置名字,那么客户端状态的name属性指向NULL指针,如果客户端为自己设置了名字,那么name属性指向一个字符串对象,该对象保存着客户端的名字

3.标志

客户端标志属性flags记录客户端的角色(role),以及客户端目前所处的状态:

typedef struct redisClient{

  int flags;

}

比如:REDIS_MASTER,  REDIS_SLABE,  REDIS_BLOCKED(表示客户端正在被brpop,blpop等命令阻塞)

4.输入缓冲区
用来保存客户端发送的命令请求:

typedef struct redisClient{

  sds querybuf;

}

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

5.命令与命令参数

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

typedef struct redisClient{

  robj **argv; //数组,数组中的每一项都是一个字符串对象

  int argc;

}

其中argv[0]是要执行的命令,之后的其他项是传给命令的参数

6.命令的实现函数

服务器根据argv[0]的值,在命令表中查找命令所对应的命令实现函数(比如:argv[0]存的是set命令)。命令和命令实现函数保存在dict结构中,键保存了命令的名字,值保存命令所对应的redisCommend结构,这个结构保存了命令的实现函数。

7.输出缓冲区

命令回复保存在客户端状态的输出缓冲区中。

缓冲区有两种:

  固定大小的字节数组

  大小可变的链表

8.身份验证

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

typedef struct redisClient{

  int authenticated;

}

如果authenticated

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄