Redis设计与实现(十二)客户端

Redis服务器是一个一对多模式的服务器程序,一个服务端可以和多个客户端建立网络连接。每个客户端可以向服务端发送命令请求。

通过上一节说到的多路复用器,文件事件处理器。让Redis可以实现一个单线程单进程的方式来处理请求(多路复用--->1个文件事件分发器--->N个处理器)。

对于每个建立连接的Redis客户端,Redis中使用了redisClient来实现保存这些Redis需要用到的信息以及相关的数据。这些数据包括:

客户端的套接字描述符,名字,标识值,正在使用的数据库的指针,该数据库的号码,当前要执行的命令,命令的参数,命令参数的个数,指向函数实现的指针,输入输出缓冲区,等等

Redis服务器状态结构的clients属性是一个链表,这个链表保存了,所有与服务器相连接的客户端的状态结构,对客户端执行批量操作,或者查找某个指定的客户端,都可以通过这个遍历这个链表来实现。

 

 客户端状态包含的属性可以分为两类:一个是比较通用的属性,另外一类是和特点功能相关的属性。其中客户端的fd套接字记录了客户端使用的套接字描述符。如果fd是-1,那么则表示这个客户端是一个假的客户端不是真实有效的客户端,一般是AOF文件来还原数据库的状态,另外一种则是Lua脚本。

如果不是-1则表示是一个正常客户端。默认情况下连接到Redis的客户端是没有名字的。

客户端的flags属性记录了客户端的角色以及客户端目前所处的状态。

flags可以是一个单个的值。也可以是多个值的二进制体现,这个属性是经常进行变动的,例如REDIS_MONITO表示Redis正在进行MONITO的命令,REDIS_BLOCKED则表示目前的这个客户端正在被BRPOP等command进行阻塞。

 

 

 

 客户端状态的输入缓冲区可以用来保存客户端的命令请求:

一个sds类型的结构用来保存querybuf(缓冲区)。如果发送了一个set key value的command。这个querybuf的就会有一个SDS的引用,这个SDS则保存了这条指令。

 

 将命令保存之后,Redis会对这个querybuf进行分析,得出命令的参数和个数之后进行保存,argv用来存储命令的参数,argv是一个数组。每一个参数都是一个正常的字面量(StringObject)

通过这个数组redis可以得到命令,然后通过一个命令对照表进行操作。

 

 输出缓冲区在每个客户端中都有两个,一个大小是固定,一个大小是可变的。固定是为了保存那些比较小的回复,例如OK,简单的字符串,整数,错误信息等。可变的是为了回复比较大的字符串,列表,集合等。

如果客户端是通过正常的网络连接进行的,在客户端使用connect函数进行连接的时候,服务器就会调用对应的连接事件处理器进行连接,为客户端创建对应的客户端状态,并且将这个客户端的状态添加到服务器状态结构clients链表的尾部

 

 一个客户端的关闭也有多种情况,如果对应的进程被杀死或者,网络连接中断都会造成客户端的关闭。

发生不符合格式的协议也会造成连接的关闭,超过timeout也会被关闭,发送的命令大小超过了缓冲区的大小也会被关闭。

 

 

 

posted @ 2020-12-21 15:13  smartcat994  阅读(131)  评论(0编辑  收藏  举报