← 返回题目列表

Redis 客户端输出缓冲区为什么会撑爆内存?如何治理?

困难 第 36 / 36 题 更新于 2026/07/30
Redis输出缓冲区内存治理

简化版

Redis 输出缓冲区用于暂存还没发给客户端的响应。客户端读得慢、返回结果太大、Pub/Sub 订阅者消费慢、复制链路阻塞时,缓冲区可能不断变大,最终导致内存飙升或连接被 Redis 断开。

详细版

Redis 处理命令后要把结果写回客户端。如果客户端网络慢、应用不读取、命令返回大结果,响应数据就会堆在服务端输出缓冲区。

普通客户端、Pub/Sub 客户端、Replica 客户端通常有不同的缓冲限制。治理时要从两边入手:服务端设置 client-output-buffer-limit,客户端避免大结果和慢消费,业务上拆分请求、限流订阅、隔离大批任务。

这类问题很容易被误判成“Redis 内存泄漏”。实际上很多时候是客户端消费能力跟不上。

完整版教学

一、输出缓冲区是什么

Redis 每个客户端连接都有输入和输出缓冲。输入缓冲保存客户端发来的命令,输出缓冲保存 Redis 准备返回但还没成功写到 socket 的响应。

如果客户端读取很快,输出缓冲只是短暂停留;如果客户端不读、网络拥塞或响应太大,缓冲就会堆积在 Redis 进程内存里。

Redis 执行命令 -> 生成响应 -> 输出缓冲区 -> TCP socket -> 客户端读取

这条链路任何一段慢,都会让前面的数据堆起来。

二、哪些场景容易撑大缓冲

第一类是大结果命令,例如 HGETALL 大 hash、SMEMBERS 大 set、LRANGE 0 -1 大列表。一次返回几十 MB,客户端稍慢就会积压。

第二类是 Pub/Sub。发布者持续推消息,订阅者处理慢,Redis 会为这个慢订阅连接缓存待发送消息。

第三类是复制。主库给从库发送复制流,如果网络慢或从库处理慢,复制缓冲会增长,影响主库内存。

三、缓冲区限制怎么理解

Redis 用 client-output-buffer-limit 限制不同客户端类型的输出缓冲。常见维度包括 hard limit、soft limit 和 soft seconds。

hard limit:超过立即断开
soft limit:持续超过一段时间才断开
soft seconds:持续时间阈值

例如 soft limit 64MB、soft seconds 60,表示客户端缓冲超过 64MB 并持续 60 秒,Redis 会断开它。这是保护实例,不是修复业务消费慢。

四、为什么不能只调大限制

调大限制会减少断连,但可能把问题转化成 Redis 内存暴涨。假设 100 个慢客户端,每个堆 50MB,就是 5GB 额外内存。

治理动作解决什么风险
调大限制降低误断连掩盖慢消费
拆分大查询减少单次响应代码改造
客户端限速降低堆积吞吐下降
隔离 Pub/Sub防止影响缓存主链路运维复杂

真正的治理要找到“谁慢”和“为什么慢”,而不是只改配置。

五、如何排查这类问题

可以用 CLIENT LIST 查看客户端输出缓冲相关字段,定位哪个连接缓冲异常。再结合客户端 IP、应用名称、命令统计、网络监控判断来源。

CLIENT LIST
INFO clients
INFO memory

如果问题来自大查询,要改命令;来自慢消费者,要优化消费逻辑或限流;来自复制,要检查网络、从库性能和复制拓扑。

六、常见误区与追问

  • 误区:Redis 内存涨就是数据 key 变多。 输出缓冲、复制缓冲、碎片和 COW 都可能增加内存。
  • 误区:客户端输出缓冲越大越安全。 缓冲太大可能保护了慢客户端,却牺牲了 Redis 实例。
  • 误区:Pub/Sub 消息很轻,不会撑内存。 慢订阅者跟不上发布速度时,消息会在连接缓冲中堆积。
  • 追问:怎么发现是哪个客户端?CLIENT LIST 看连接来源和缓冲字段,再关联应用日志。
  • 追问:大结果命令怎么治理? 改成分页、SCAN/HSCAN/SSCAN、字段读取或业务索引,不要一次返回全量。

七、加强记忆

记忆钩子:输出缓冲区像 Redis 门口的快递架,客户端不取件、快递又一直来,架子会先爆,不是仓库里的商品突然变多。

回答这题时抓住“响应发不出去就堆在 Redis 内存里”这个核心,再展开慢客户端、大结果、Pub/Sub、复制和配置限制,逻辑会很清楚。