redis客户端在于redis服务端相互交互时,服务端会为每个客户端分别设置输入缓存区和输出缓存区,我们知道redis是基于内存的非关系型数据库,所以这两部分缓存区的数据依然是保存在内存中,如果这两部分很大的话会占用redis很大的内存。模型图如下图所示:
使用info命令查看当前redis客户端连接数及当前缓存区的使用量
那么什么是输入缓存区和输出缓存区呢?
输入缓存区:用于保存客户端发送的请求,输入缓存区的大小会根据请求数据的大小动态变化,1GB是输入缓存区最大的容量,如果超出最大容量该客户端便会被关闭。
输出缓存区:用于保存执行请求后的返回结果,每个客户端有两个缓存区,一个是固定客户端缓存区(用于保存那些长度比较小的返回值,如一些比较短的字符串或整数值);一个是可变客户端缓存区(用于保存那些长度比较大的返回值,如长度比较大的字符串、大集合等)。
服务器采用软性限制和硬性限制两种方式限制输出缓存区的大小。
软性限制:如果软性限制所设置的大小小于输出缓冲区的大小,且输出缓冲区的大小不大于硬性限制所设置的大小,那么服务器会使用客户端状态结构的 obuf_soft_limit_reached_time 属性来记录客户端达到软性限制的起始时间。之后服务器会继续监视客户端,如果这个缓冲区的大小一直超出软性限制,并且持续时间超过服务器设定的时长,那么服务器将会关闭这个客户端。相反地,如果输出缓冲区的大小在指定时间范围之内没有超过软性限制,那么这个客户端不会被关闭,并且 obuf_soft_limit_reached_time 属性的值也会被设置为 0。
如果输出缓存区的大小大于硬性限制,那么客户端会立即关闭。
在redis配置文件中,可以对软性限制和硬性限制进行设置:
第一行代码表示:对于普通客户端来说,限制为0,也就是不限制。因为普通客户端通常采用阻塞式的消息应答模式,通常情况下不会导致redis输出缓存区数据堆积膨胀。
第二行代码表示:对于slave客户端来说,硬性限制是256M,软性限制是当客户端缓冲区大小持续60秒超过64M,则关闭客户端连接。
第三行代码表示:对于Pub/Sub客户端(也就是发布/订阅模式),硬性限制是32M,当输出缓冲区超过32M时,会关闭连接。软性限制是当客户端缓冲区大小持续60秒超过8M,则关闭客户端连接;