《Redis设计与实现》读书笔记(十九) ——Redis客户端创建关闭及客户端总结

《Redis设计与实现》读书笔记(十九) ——Redis客户端创建关闭及客户端总结

(原创内容,转载请注明来源,谢谢)

一、客户端的创建于关闭

1、普通客户端连接

普通的客户端,通过connect命令连接上服务器后,会被redis将客户端的状态结构体加入到redisServer的链表属性clients的末尾。

下图表示c1比c2先连上的redis服务器 。

2、普通客户端关闭

客户端关闭有下述情况:

1)客户端进程退出,或被kill,或成为client kill的目标。

2)客户端发送不符合协议格式的请求,或客户端发送命令超出默认的1GB大小的请求,或服务器回复给客户端的内容超过输出缓冲区规定大小的内容。

3)用户设置空转时限而客户端达到此时限(该条件有例外,如客户端是主服务器、从服务器、客户端被阻塞、客户端正在发布订阅,就算超过时限也不会被关闭)。

服务器通过两种方式来先知客户端输出缓冲区的大小:

1)硬性限制

规定一个值,输出缓冲区超过这个值,立刻关闭该客户端。

2)软性限制

当超过这个值,但是还没超过硬性限制,会写入上述提及redis客户端结构体中obuf_soft_limit_reached_time属性,作为超过软性限制开始的时间,之后服务器会持续监控此客户端,如果超出规定的软性限制的时间,则关闭客户端;如果软性限制时间之前,客户端输出缓冲区内容减小到软性限制之前,则不关闭客户端,并且将obuf_soft_limit_reached_time的值清零。

使用client-output-buffer-limit可以为普通客户端、从服务器客户端、执行发布订阅客户端,设置硬性限制和软性限制。

格式是client-output-buffer-limit<class> <hard limit> <soft limit> <soft seconds>

其中class表示客户端的类型,包括normal、slave、pubsub。hard和soft的limit是设置大小,例如256mb、16mb等,如果是0的话表示不限制大小。

3、lua伪客户端

lua伪客户端不是存放在redisServer的clients链表中,而是单独有一个redisClient类型的属性lua_client,用于存放redis的lua伪客户端。该客户端创建后,不会关闭,直到服务器关闭才会关闭。

4、AOF伪客户端

服务器载入aof文件时,会创建aof伪客户端,并且载入完毕后关闭该客户端。

四、总结

1、redis服务器采用clients链表,保存客户端的信息,链表里面每个元素都是一个redisClient结构体。新连接的客户端会加到链表的最后。

2、redisClient中,flag属性记录客户端当前的状态,主要是区分客户端是否主从、发布订阅、阻塞非阻塞、强制AOF等。

3、客户端命令会被记录到redisClient的querybuf中,采用sds进行保存;记录完成后,redis会分析内容,并把参数存到argv数组,参数个数存到argc,其中argv[0]是命令,后续的是参数;分析完毕后,redis会查找保存在服务器中的命令表,通过argv[0]找到与其对应的redisCommand结构,并用指针cmd指向该结构。

3、redis服务器执行完命令后,会将内容存到输出缓冲区。redis给每个客户端都设置了固定大小缓冲区和可变大小缓冲区两种,固定大小缓冲区默认记录16KB的信息,通常用于记录短的回复,存于数组中,并另用一个字段记录当前使用的字节数。如果输出结果超过16KB,或者原先在固定大小中随着执行期超过了16KB,redis都将把结果存到可变大小缓冲区,该缓冲区根据实际大小,把每个结果存在一个字符串对象中,总的用一个链表串起来。

4、客户端中还会记录连接上服务器的时间、空转时间、超出软性限制大小的时间。

5、当主动或被迫关闭客户端、发送请求不符合格式、空转超时且不符合特殊条件(主、从、阻塞、发布订阅)、超出输出缓冲区硬性限制、输出缓冲区超出软性限制且超出规定时间等,都会造成客户端被关闭。其中硬性限制和软性限制以及软性限制的时间,都可以配置。

6、redis会创建一个伪客户端,专门用于处理Lua脚本,其存放在单独的一个属性中,不和普通客户端存在数组。且创建后,会保存在redis的整个生命周期,直到服务器关闭。

7、AOF伪客户端,是在载入aof的时候创建,载入完毕就关闭。

——written by linhxx 2017.09.08

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏阿杜的世界

【转】Dubbo架构设计详解总体架构核心要点参考资料

Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度...

12550
来自专栏农夫安全

渗透测试之子域名枚举

0x00 前言 首先对这些github上开源工具的作者表示崇高的敬意,农夫会将这种开源的精神传承下去。 0x01 Sublist3r:子域名快速枚举工具...

36980
来自专栏周明礼的专栏

一步一步带你搭建一个“摩登”的前端开发环境

最近几年也陆续推出了多种不同的js类型系统用于增强js的健壮性,其中像 typescript 就是其中的佼佼者。当然我今天要讲的并不是typescript,而是...

1.5K00
来自专栏博客园迁移

redis见解

http://blog.csdn.net/zhiguozhu/article/details/50517527 Redis 原生session与redis中的s...

23510
来自专栏用户画像

Matlab 读写文件

一、读取文本文件 思路: 1、用fopen来打开一个文件句柄 2、用fgetl来获得文件中的一行,如果文件已经结束,fgetl会返回-1 3、用fclo...

7530
来自专栏Esofar 开发日记

[译]RabbitMQ教程C#版 - 远程过程调用(RPC)

但是如果我们想要运行一个在远程计算机上的函数并等待其结果呢?这将是另外一回事了。这种模式通常被称为 远程过程调用 或 RPC 。

13520
来自专栏月牙寂

k8s源码分析------第三方库go-restful分析

第一时间获取文章,可以关注本人公众号 月牙寂道长 yueyajidaozhang

42560
来自专栏后台全栈之路

基于汇编的 C/C++ 协程 - 切换上下文

既然本系列讲的是基于汇编的 C/C++ 协程,那么这篇文章我们就来讲讲使用汇编来进行上下文切换的原理。

52260
来自专栏Java架构

阿里分布式服务框架Dubbo的架构总结总体架构参考补充

21240
来自专栏张首富-小白的成长历程

redis缓存服务器

#你当前没有指定配置文件,以默认的配置文件启动,如果你想指定配置文件你可以redis-server 文件所在位置

62820

扫码关注云+社区

领取腾讯云代金券