《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 条评论
登录 后参与评论

相关文章

来自专栏代码世界

Python之线程

操作系统线程理论 线程概念的引入背景 进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种...

4928
来自专栏用户画像

Matlab 读写文件

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

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

redis缓存服务器

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

3492
来自专栏技术之路

go微服务框架go-micro深度学习(一) 整体架构介绍

      产品嘴里的一个小项目,从立项到开发上线,随着时间和需求的不断激增,会越来越复杂,变成一个大项目,如果前期项目架构没设计的不好,代码会越来越臃肿,难以...

7173
来自专栏Java技术栈

分布式 | Dubbo 架构设计详解

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

1422
来自专栏Esofar 开发日记

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

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

1150
来自专栏Esofar 开发日记

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

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

902
来自专栏博客园迁移

redis见解

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

1411
来自专栏编程一生

漫画:Linux中/etc/resolv.conf文件和puppet工具解析

1386
来自专栏周明礼的专栏

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

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

1.5K0

扫码关注云+社区