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

相关文章

来自专栏小筱月

SSM整合开发

controller:作为请求转发,调用service接口处理逻辑,页面所有路径的访问方法:控制层的命名空间+@RequestMapping的value ser...

751
来自专栏大学生计算机视觉学习DeepLearning

c++ 网络编程(五)TCP/IP LINUX下 socket编程 多种I/O函数 -以及readv和writev函数用法

原文链接:https://www.cnblogs.com/DOMLX/p/9614056.html

815
来自专栏北京马哥教育

一篇文章带你梳理Python Django的正确的学习方法!

? 作者:地球的外星人君 来源: https://www.zhihu.com/question/26235428/answer/170250328 Djang...

2566
来自专栏数据结构笔记

python爬虫系列之 requests: 让 HTTP 服务人类

比想象中要简单的多吧,只要把要访问的网址当作参数传递给requests.get方法,就可以获得所请求的网页。

532
来自专栏企鹅号快讯

讲义15:服务器端编程:Request&Response

一、内容提要 B/S模型 Reponse对象 Request 对象 二、内容及操作步骤 1. B/S模型 Browser: 浏览器 Server: Web 服务...

1906
来自专栏一个会写诗的程序员的博客

Spring Boot 使用 Spring Session 集成 Redis 实现Session共享Spring Boot 使用 Spring Session 集成 Redis 实现Session共享

通常在web开发中,Session 会话管理是很重要的一部分,用于存储与用户相关的一些数据。在Java Web 系统中的 Session一般由 Tomcat 容...

1525
来自专栏名山丶深处

springboot集成schedule(深度理解)

2785
来自专栏Linyb极客之路

工作流引擎之activiti中的排他网关和并行网关

排他网关.png

981
来自专栏逸鹏说道

Python3 与 C# 并发编程之~ 进程实战篇

之前说过 Queue:在 Process之间使用没问题,用到 Pool,就使用 Manager().xxx, Value和 Array,就不太一样了:

904
来自专栏龙首琴剑庐

Spring4+Spring MVC+MyBatis整合思路

1、Spring框架的搭建 这个很简单,只需要web容器中注册org.springframework.web.context.ContextLoaderList...

3005

扫码关注云+社区