更多技术文章,请关注我的个人博客 www.immaxfang.com 和小公众号
Max的学习札记
。
概述
Redis 的 client-output-buffer-limit 可以用来强制断开无法足够快从 redis 服务器端读取数据的客户端。
保护机制规则如下:
- [hard limit] 大小限制,当某一客户端缓冲区超过设定值后,直接关闭连接。
- [soft limit] 持续时间限制,当某一客户端缓冲区持续一段时间占用过大空间时关闭连接。
该参数一般用在以下几类客户端中:
- 普通 client,包括 monitor
- 主从同步时的 slave client
- Pub/Sub 模式中的 client
配置介绍与分析
该参数的配置语法:
client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
配置实例:
# 普通client buffer限制
client-output-buffer-limit normal 0 0 0
# slave client buffer限制
client-output-buffer-limit slave 256mb 64mb 60
# pubsub client buffer限制
client-output-buffer-limit pubsub 32mb 8mb 60
- client-output-buffer-limit normal 0 0 0
将 hard limit 和 soft limit 同时设置为 0,则表示关闭该限制。
- client-output-buffer-limit slave 256mb 64mb 60
该配置表示,对于 slave 客户端来说,如果 output-buffer 占用内存达到 256M 或者超过 64M 的时间达到 60s,则关闭客户端连接。
- client-output-buffer-limit pubsub 32mb 8mb 60
该配置表示,对于 Pub/Sub 客户端来说,若 output-buffer 占用内存达到 32M 或者超过 8M 的时间达到 60s,则关闭客户端连接。
概括说明:
一般情况下,对于普通客户端,client-output-buffer 是不设限制的,因为 server 只会在 client 请求数据的时候才会发送,不会产生积压。
而在 server 主动发送,client 来处理的场景下,这种一般都是异步处理的,会划出一个缓冲区来“暂存”未处理的数据,若 server 发送数据比 client 处理数据快时,就会发生缓冲区积压。对于用作 Pub/Sub 和 slave 的客户端,server 会主动把数据推送给他们,故需要设置 client-output-buffer 的限制。
示例分析
下面我们以主从同步时的 slave 客户端,来具体分析下。
在 redis 在主从同步时,master 会为 slave 创建一个输出缓冲区。在 master 保存 rdb,将 rdb 文件传输给 slave,slave 加载 rdb 完成之前,master 会将接收到的所有写命令,写入到内存中的这个输出缓冲区去。
若 rdb 的保存,传输,加载耗时过长,或者在此期间的写命令过多,则可能会造成超过缓冲区限制,造成 master 和 slave 的连接断开。此时则需要适当调整下 client-output-buffer-limit slave
配置。
源码浅析-主从同步时 output buffer 使用
基于 redis5.0 版本源码
redis server 通过 addReply 将数据发送给客户端,以下源码见 https://github.com/redis/redis/blob/5.0/src/networking.c#L190-L211
/* Add the object 'obj' string representation to the client output buffer. */
void addReply(client *c, robj *obj) {
if (prepareClientToWrite(c) != C_OK) return;
if (sdsEncodedObject(obj)) {
if (_addReplyToBuffer(c,obj->ptr,sdslen<