客户端
2018-12-07 本文已影响0人
简书徐小耳
redisClient代表客户端的状态结构,其内部包含的内容如下:
- 客户端的socket描述符
- 客户端的名字
- 客户端的标志值
- 指向客户端正在拾遗的数据库指针,以及该数据库的号码
- 客户端当前要执行的命令,命令参数,命令参数的个数,以及指向命令实现函数的指针
- 客户端的输入和输出缓冲区
- 客户端的复制状态信息,以及进行复制所需要的数据结构
- 客户端执行BRPOP,BLPOP等列表阻塞命令时使用的数据结构
- 客户端的事务状态,以及指向watch命令时用到的数据结构
- 客户端执行发布与订阅功能时用到的数据结构
- 客户端的身份验证标志
- 客户端的创建时间,客户端和服务器最后一次的通信时间,以及客户端的输出缓冲区大小超出软性限制的时间
redis的服务器端通过一个链表保存一连串的客户端
客户端的socket描述符
- 就是一个int 类型的数值 我们用fd表示
- fd 等于-1 代表伪客户端,伪客户端处理的命令请求来源于AOF文件或者Lua脚本
- 大于 -1的整数就是代表普通的客户端与服务端通信的socket
客户端的名字
- 默认情况下client 是没有名字的 可以执行client setname 命令设置名字
- 如果有名字 则记录在redisClient的name属性里面
客户端的的标志值
- int flags 可以是单个标志 flags=<flag>,也可以是多个标志的二进制或 比如 flags=<flag1>| <flag2>
- 在主从复制期间,主服务器会成为从服务器的客户端,而从服务器也会成为主服务器的客户端,REDIS_MASTER标识一个客户端是主服务器,REDIS_SLAVE标识一个客户端是一个从服务器
- REDIS_PER_PSYNC标识客户端代表的是一个版本低于Redis2.8的从服务器
-
其余如下入,也就是说flags只是嗲表此时客户端正在扮演哪些角色
image.png
image.png - 以上的标识都定义在redis.h文件中
输入缓冲区
- 用来保存客户端发送的命令
- 缓冲区是采用SDS对象-querybuf
- 缓冲区的大小最大不能超过1GB,否则服务器将关闭这个客户端
-
SDS可以动态扩或缩
image.png
命令与命令参数
- 当服务器接收到命令参数之后可以得出这个命令参数以及命令参数的个数,并将其分别保存到客户端的argv(robj)和argc(int)属性
- argv是一个数组,数组中的每一项都是字符串对象,其中argv[0]是要执行的命令而之后的就是传给命令的参数
-
下图中argc的属性等于3而不是2是因为set命令本身也是参数
image.png
命令的实现函数
-
当我们得到命令和参数后我们就会去命令表中去寻找对应的实现函数
-
命令表示一个字典,key是命令的sds对象,value则是redisCommand结构,该结构保存了命令的实现函数,命令的标志,命令应该给定的参数个数,命令的总执行次数和总耗时长度等统计信息
-
找到后就将redisclient的参数cmd 执行rediscommand
image.png -
命令表的查找不区分输入字母的大小写
输出缓冲区
-
执行命令得到回复会被放在客户端状态的输出缓冲区
-
每个客户端都能得到两个输出缓冲区,一个是固定大小,一个是大小可悲
-
固定大小用于保存哪些长度比较小的回复,比如ok,简单字符串,整数值等
-
可变大小用于保存哪些长度较大的回复
-
固定大小的属性如下:两个属性分别 为 buf 和bufpos
image.png -
其中buf为一个字节数组,bufpos类似于游标
-
当buf数组使用完了或者因为太大无法存放才会使用可变大小
image.png -
可变大小缓冲区由reply链表和一个或多个字符串对象组成
-
链表内部就是字符串对象
image.png
身份验证
- 属性是int 类型的authenticated 用于记录客户端是否通过了身份验证
- 0则代表未通过,1代表通过
- 0的时候只允许auth命令,其他都拒接
- 上述只是服务器开启身份验证的时候,如果没有开启就算是authenticated=0 也不会拦截
时间
- ctime:记录了客户端的创建时间,
lastinteraction:记录了客户端与服务器最后一次进行互动的时间
obuf_soft_limit_reached_time :记录了输出缓冲区第一次到软性限制的时间
关闭普通客户端
关闭的原因如下:
- 客户端进程退出或者被杀死
- 客户端向服务器发送了带有不符合协议格式的命令和请求
- 如果客户端被执行了client kill 命令
-
用户为服务器设置了timeout,当客户端的空转时间超过timeout 则被关闭
image.png - 如果输入缓冲大小超过了1GB则被关闭(命令缓冲)
- 如果输出缓冲大小超过缓冲区限制也被关闭(回复大小)
为了避免输出缓冲过大,服务器设置了hardlimit和softlimt
- hardlimit 超过了硬性大小就关闭客户端
- softlimit 超过了输出软性缓冲大小单但是没超过硬性大小,则记录下超出的时候时间obuf_soft_limit_reached_time ,之后如果一直超出且持续时间超过服务器的设置时间 那么我们就关闭