单机 redis pub/sub 实际吞吐极限由内存带宽、网络 i/o 和客户端处理能力共同决定;当 publish 超 5–10 万 qps 且订阅者 > 100 时,会出现延迟抖动和丢消息,这是架构层溢出信号,非配置可调。

单机 Redis Pub/Sub 的实际吞吐量极限不是固定数字,而是由三个硬性瓶颈共同决定的:内存带宽、网络 I/O 和客户端处理能力。当 PUBLISH 频率超过 5–10 万 QPS 且活跃订阅者 > 100 时,延迟抖动和丢消息会明显上升——这不是配置能调出来的,是架构层面的溢出信号。
为什么 benchmark 显示的 QPS 不可信
默认 redis-benchmark -t publish,subscribe 创建大量短连接 + 独立 pipeline,完全脱离真实场景。它只测“发出去花了多久”,不测订阅端是否来得及 READ、缓冲区是否溢出、TCP 是否重传。
- 真实压测必须固定连接数:
redis-benchmark -c 50 -n 500000 -t publish -P 1 -d 64(50 连接、单 pipeline、64 字节消息) - 同时用另一个终端跑
redis-cli --csv PSUBSCRIBE "channel*",观察实际接收速率,别信 benchmark 输出的“requests per second” - 务必搭配
redis-cli --stat看net_input_bytes和intrinsic-latency,比 CPU 使用率更能反映瓶颈
client-output-buffer-limit pubsub 是关键开关
Redis 默认对每个订阅者设了输出缓冲区上限:client-output-buffer-limit pubsub 32mb 8mb 60。意思是:单个订阅连接缓冲区超 32MB,或连续 60 秒超 8MB,就强制断连。慢消费者、大消息、网络抖动都极易触发。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 必须按预期消息体积和消费速度调整,例如:
client-output-buffer-limit pubsub 256mb 64mb 300 - 调整后需监控
INFO clients中的client_longest_output_list和client_biggest_input_buf - 注意:该限制对
PSUBSCRIBE同样生效,模式匹配导致的隐式多频道订阅会让缓冲区压力翻倍
PUBLISH 大于 100KB 就会卡主线程
Redis 单线程串行执行 PUBLISH 全流程:序列化 → 内存拷贝 → 遍历所有订阅者 → 发送。一个 2MB 消息可能让主线程停顿 200ms 以上,期间所有命令(包括 PING)全部排队。
- 必须控制序列化后 payload ≤ 102400 字节(100KB),
proto-max-bulk-len的 512MB 是陷阱,别信 - PUBLISH 前检查长度,必须在最终序列化之后做——JSON 中文转义会让原始字符串膨胀 2–3 倍
- 订阅端也要预检:
redis.Redis(decode_responses=False)+if len(msg.get("data")) > 102400: continue
真正卡住吞吐的,往往不是 Redis 配置,而是业务层没意识到 Pub/Sub 是广播模型:加机器不扩容、大消息不拒绝、退订不及时、模式订阅失控——这些细节比调参重要得多。










