客户端

本文详细解读了Redis服务器中客户端状态结构,包括通用属性如ID、名字和标识,以及与功能相关的特性如输入/输出缓冲区、身份验证和时间戳。介绍了客户端创建与关闭机制,并重点展示了Redis客户端状态管理的关键部分。
摘要由CSDN通过智能技术生成

对于每个与服务器进行连接的客户端,服务器都会为客户端建立相应的client结构(客户端状态),这个结构保存了客户端当前的状态信息,以及执行相关功能用到的数据结构。

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

1、客户端属性

客户端状态包含的属性可以分为两类

一类是比较通用的属性,这些属性很少与特定功能相关,无论客户端执行的是什么工作,它们都要用到这些属性。

另外一类是和特定功能相关的属性,比如操作数据库时对应的redisDb,执行事务时需要用到的mstate属性,执行watch命令时需要用到的watched_keys属性。

(1)客户端id

该属性记录了分配的客户端id。根据客户端类型的不同,id属性的值不同,初始值从1开始。

伪客户端的id属性的值 为UINT64_MAX。伪客户端处理的命令请示来源于aof文件,不是网络,所以这种客户端不需要套接字连接。

普通客户端的id属性值是通过redisServer.next_client_id来递增分配。在处理客户端连接时acceptTcpHandler中会创建客户端分配。

(2)名字

在默认情况下,一个连接到服务器的客户端是没有名字的。使用CLIENT setname命令可以为客户端设置一个名字,让客户端的身份变得更清晰。

(3)标识

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

flags属性的值可以是单个标志,也可以是多个标志的二进制或。每个标志使用一个常量表示,一部分标记记录了客户端的角色:

CLIENT_MASTER客户端代表的是一个主服务器
CLIENT_SLAVE客户端代表的是一个从服务器
CLIENT_PRE_PSYNC客户端代表的是一个版本低于Redis2.8的从服务器,主服务器不能使用PSYNC命令与这个从服务器进行同步。这个标志只能在CLIENT_SLAVE标志处于打开状态时使用
CLIENT_LUA客户端是专门用于处理Lua脚本里面包含的Redis命令的伪客户端
CLIENT_MONITOR客户端正在执行monitor命令
CLIENT_UNIX_SOCKET服务器使用unix套接字来连接客户端
CLIENT_BLOCKED客户端下正在被BRPOP,BLPOP等命令阻塞
CLIENT_UNBLOCKED客户端已经从CLIENT_BLOCKED标志所表示的阻塞状态中脱离出来,不再阻塞,此标志只能在CLIENT_BLOCKED标志已经打开的情况下使用
CLIENT_MULTI客户端正在执行事务
CLIENT_DIRTY_CAS事务使用watch命令监视的数据库键已经被修改,exec命令必然会执行失败,只能在客户端打开了CLIETN_MULTI标志的情况下使用
CLIENT_DIRTY_EXEC事务在命令入队时出现了错误,exec命令必然会执行失败,只能在客户端打开了CLIETN_MULTI标志的情况下使用
CLIENT_CLOSE_ASAP客户端的输出缓冲区大小超出了服务器允许的范围,服务器会在下一次执行serverCron函数时关闭这个客户端,以免服务器的稳定性受到这个客户端影响,积存在输出缓冲区中的所有内容会直接被释放,不会返回给客户端
CLIENT_CLOSE_AFTER_REPLY有用户对这个客户端执行了CLIENT KILL命令,或者客户端发送给服务器的命令请求中包含了错误的协议内容。服务器会将客户端积存在缓冲区中的所有内容发送给客户端,然后关闭客户端。
CLIENT_ASKING客户端向集群节点发送了ASKING命令
CLIENT_FORCE_AOF强制服务器将当前执行的命令写入到aof文件里面
CLIENT_FORCE_REPL强制主服务器将当前执行的命令复制给所有从服务器

 

(4)输入缓冲区

querybuf用于保存客户端发送的命令请求。输入缓冲区的大小会根据输入内容动态地缩小或者扩大,但它的最大大小不能超过1GB,否则服务器将关闭这个客户端

(5)命令和命令参数

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

argv属性是一个数组,数组中的每个项都是一个字符串对象,其中argv[0]是要执行的命令,而之后的其他项则是传给命令的参数。

argc属性则负责记录argv数组的长度。

(6)命令的实现函数

当服务器从协议内容中分析并得出argv属性和argc属性的值之后,服务器将根据项argv[0]的值,在命令表中查找命令所对应的命令实现函数。之后服务器就可以使用cmd属性所指向的redisCommand结构,以及argv,argc属性中保存的命令参数信息,调用 命令实现函数,执行客户端指定的命令。

(7)输出缓冲区

执行命令所得的命令回复会被保存在客户端状态的输出缓冲区里面,每个客户端都有两个输出缓冲区可用,buf缓冲区的大小是固定的,reply缓冲区的大小是可变的

(8)身份验证

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

如果authenticated的值为0,表示客户端未通过身份验证,如果值为1,表示客户端通过了身份验证。

(9)时间

客户端有几个与时间相关的属性ctime,lastinteraction, obuf_soft_limit_reached_time.

ctime属性记录了创建客户端的时间,这个时间可以用来计算客户端与服务器已经连接了多少秒。

lastinteraction属性记录了客户端与服务器最后一次进行互动的时间,这里的互动时间可以是客户端向服务器发送命令请求,也可以服务器向客户端发送命令回复。可以用来计算客户端的空转时间。

2、客户端创建和关闭

(1)普通客户端创建

通过网络连接与服务器进行连接的普通客户端,在客户端使用connect函数连接到服务器时,服务器会调用连接事件处理器acceptTcpHandler,为客户端创建相应的客户端状态,并将这个新的客户端状态添加到服务器状态结构clients链表的末尾。

(2)关闭普通客户端

  • 如果客户端进程退出或者被 杀死,那么客户端与服务器之间的网络连接将被关闭,从而造成客户端被关闭
  • 如果客户端向服务器发送了带有不符合协议格式的命令请求,那么这个客户端也会被服务器关闭
  • 如果客户端成为了CLIENT KILL命令的目标,那么它也会被关闭
  • 如果用户为服务设置了timeout配置选项,那么当客户端的空转时间超过timeout选项设置的值时, 客户端将被关闭。不过timeout选项有一些例外情况:如果客户端是主服务器(打开了CLIENT_MASTER标志),从服务顺路(打开 了CLIENT_SLAVE标志),正在被BLPOP等命令阻塞(打开 了CLIENT_BLOCKED标志),或者正在执行SUBSCRIBE,PSUBSCRIBE等订阅命令,那么即使客户端的空转时间超过了timeout选项的值,客户端也不会被服务器关闭
  • 如果客户端发送的命令请求的大小超过了输入缓冲区的限制大小(默认为1GB),那么这个客户端会被服务器关闭
  • 如果要发送给客户端的命令回复的大小超过了输出缓冲区的限制大小,那么这个客户端会被服务器关闭。

(3)Lua脚本的伪客户端

服务器会在初始化时创建负责执行Lua脚本中包含的Redis命令的伪客户端,并将这个伪客户端关联在服务器状态结构的lua_client属性中。

lua_client伪客户端在服务器运行的整个生命期中会一直存在,只有服务器被关闭时,这个客户端才会被关闭

(4)aof文件的伪客户端

服务器在载入aof文件时,会创建用于执行aof文件包含的redis命令的伪客户端,并在载入完成之后,关闭这个伪客户端。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值