认识 Redis client-output-buffer-limit 参数与源码分析

本文介绍了 Redis 中的 client-output-buffer-limit 参数,用于防止客户端缓冲区过大导致的连接关闭。详细分析了该参数在主从同步、普通客户端和 Pub/Sub 客户端中的应用,并通过源码探讨了主从同步时输出缓冲区的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

更多技术文章,请关注我的个人博客 www.immaxfang.com 和小公众号 Max的学习札记

概述

Redis 的 client-output-buffer-limit 可以用来强制断开无法足够快从 redis 服务器端读取数据的客户端。
保护机制规则如下:

  1. [hard limit] 大小限制,当某一客户端缓冲区超过设定值后,直接关闭连接。
  2. [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<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值