《Redis设计与实现》之第十三章:Redis客户端

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

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

一,客户端属性

分两类:

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

  特定功能相关的属性:比如:操作数据库时用到的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=0,表示客户端没有通过身份验证。如果authenticated=1,表示客户端通过了身份验证。

注意:authenticated属性只有在服务器启用了身份验证功能时使用。

9.时间

typedef struct redisClient{

  time_t  ctime;//创建客户端的时间

  time_t  lastinteraction;//客户端与服务器最后一次进行互动的时间,

  time_t  obuf_soft_limit_reached_time;//输出缓冲区第一次到达软性限制的时间

}

二,客户端的创建和关闭

1.创建普通客户端

客户端使用connect函数连接到服务器,服务器会调用连接事件处理器,为客户端创建相应的客户端状态,并把这个新的客户端状态添加到服务器状态结构clients链表的尾部。

2.关闭普通客户端

为了避免客户端的回复过大,占用过多的服务器资源,服务器会时刻检查客户端的输出缓冲区大小,并在缓冲区的大小超过范围时,执行相应的限制操作。有两种模式来限制客户端输出缓冲区的大小:

硬性限制:如果输出缓冲区的大小超过硬性限制所设置的大小,那么服务器立刻关闭客户端

软性限制:客户端在一定时间内,一直超过超过服务器设置的软性限制,客户端也会被关闭

原文地址:https://www.cnblogs.com/inspred/p/10722262.html