Redis在处理客户端请求时,并不是每条命令执行完就立刻把结果发出去。响应数据先写入每个客户端专属的输出缓冲区,再由事件循环异步发送到网络。正常情况下这块缓冲区很小,数据写完就被客户端及时读走。但一旦某个客户端出了问题——比如网络阻塞、读取速度跟不上、或者订阅了大量频道的消息来不及消费——缓冲区里的数据就会越积越多。如果不加限制,Redis进程内存会被这些堆积数据逐步吃光,最终触发OOM或者被系统杀掉。client-output-buffer-limit就是为此而生的保护机制。

client-output-buffer-limit的基本语法与参数含义
这个参数可以在redis.conf中配置,也可以通过CONFIG SET命令在线修改。完整语法如下:
client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
其中class表示客户端类型,hard limit是硬限制,soft limit是软限制,soft seconds是软限制的持续时间。三个维度组合起来决定了一个客户端何时会被强制断开:
- 硬限制:缓冲区大小一旦达到这个值,Redis立即关闭该客户端连接,没有任何商量余地。
- 软限制:缓冲区大小超过软限制但未达到硬限制时,开始计时。
- 软时间:如果缓冲区持续超过软限制的时间达到soft seconds秒,连接同样会被关闭。只有缓冲区降回软限制以下,计时器才会重置。
举个例子,配置为client-output-buffer-limit normal 0 0 0时,表示对普通客户端完全不限制;而client-output-buffer-limit replica 256mb 64mb 60表示:复制连接的缓冲区达到256MB立即断开,或者持续60秒超过64MB也断开。这种双阈值设计既防住了突发大流量,也容忍了短暂的高峰。
三种客户端类型的区别与默认值
Redis将客户端分为三类,每类的默认限制策略差异很大,理解这个差异是正确调参的前提。
第一类是normal,即普通客户端连接。默认值为0 0 0,也就是不限制。为什么普通客户端可以不限?因为普通客户端通常是阻塞式读取,请求-响应模式下一来一回,客户端不及时读走数据,自己的业务也会卡住,自然会主动处理。但这不意味着永远安全,如果业务代码里有客户端只发命令不读结果的异常用法,仍可能撑爆缓冲区,这种情况下可以手动设置限制。
第二类是replica,即主从复制连接,旧版本叫slave。主节点需要把写命令源源不断推送给从节点,如果从节点网络慢或者处理不过来,主节点的输出缓冲区就会持续增长。一旦这个从节点的缓冲区占用了大量内存,主节点本身的服务质量就会受影响。因此默认值是256mb 64mb 60,超限后主节点会主动断开该从节点,从节点重连后再重新同步。虽然全量同步开销大,但总比拖垮主节点强。
第三类是pubsub,即发布订阅模式的客户端。订阅者收消息是被动的,如果订阅者消费太慢,缓冲区会无限堆积,而且订阅者自己往往感知不到问题。所以这类连接的默认限制更严格一些,常见默认值为32mb 8mb 60。
可以通过CLIENT LIST命令观察每个客户端的当前状态,其中omem字段就是输出缓冲区已占用的字节数,排查慢客户端时非常实用:
127.0.0.1:6379> CLIENT LIST id=3 addr=192.168.0.15:52100 omem=12345678 events=w cmd=subscribe
生产环境中的调优实践与常见问题
调整这个参数前,先要搞清楚为什么要调。最常见的场景是主从复制频繁断连。如果从节点写入量大、网络带宽有限,复制缓冲区经常超过256MB被主节点踢掉,从节点重连后又触发全量同步,形成恶性循环。这时候盲目调大限制只是权宜之计,更好的做法是排查网络质量、控制写入峰值,或者考虑启用无盘复制减少磁盘IO瓶颈。确实需要调大时,务必评估主节点最大内存能否承受,比如设置512MB的硬限制,理论上每个慢从节点都可能占用这么多内存。
另一个典型问题是Pub/Sub慢消费者。使用Redis做消息分发时,如果某个订阅服务卡死,Redis会在60秒后把它踢掉,之后该服务重连又继续堆积。这时需要做的是让订阅端处理好消费逻辑,或者在应用层监控订阅者的消费延迟。对于改用Redis Stream的场景,消费者不再是被动推送模式,缓冲区压力会小很多。
在线修改配置时要注意持久化问题,CONFIG SET只对当前进程生效,重启后会回到配置文件的值,所以调完后记得同步修改redis.conf。验证配置是否生效可以执行:
127.0.0.1:6379> CONFIG GET client-output-buffer-limit 1) "client-output-buffer-limit" 2) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
最后提醒一点,Redis 2.8.12之后还允许为normal类客户端单独设置,配合client-output-buffer-limit normal 10mb 2mb 30这类配置,可以有效防御那些不读响应的异常客户端。但阈值别设太小,否则批量执行大批量命令、结果集较大的正常客户端也可能被误杀,反而造成业务故障。监控上建议持续关注INFO clients中的blocked_clients指标以及各客户端的omem分布,提前发现慢消费趋势,比事后救火从容得多。
Redis缓冲区client-output-buffer-limitRedis配置优化修改时间:2026-09-03 14:10:58