redis pub/sub真实p90延迟最低为0.3ms(300μs),需用host网络绕过docker虚拟栈、禁用conntrack、避免buffer溢出及redis-benchmark误测,客户端调度与tcp栈才是最后100μs瓶颈。

Redis PUB/SUB 本身做不到微秒级延迟——p90 延迟压测下最低也只能到 0.3ms(300 微秒),且这需要严苛的网络与客户端配置。所谓“微秒级”是常见误传,真实场景中 100–300μs 是当前物理和协议栈限制下的合理下限。
用 host 网络绕过 Docker 虚拟网桥开销
Docker 默认 --network bridge 是低延迟交易系统里最常被忽略的瓶颈:veth → docker0 → iptables → NAT 每跳加 0.5–2ms,直接把端到端延迟从 sub-ms 推高到 6–12ms。
- 改用
--network host后实测 p90 延迟回落至0.3–0.8ms(即 300–800μs) - 注意:
redis-cli连接必须用127.0.0.1:6379,不能用localhost(否则可能走 Unix socket,容器内不可用) - 若无法用 host 网络,可禁用 conntrack:
sysctl -w net.netfilter.nf_conntrack_enable=0,但需评估对其他容器的影响 - 同一宿主机上的发布者与订阅者,优先共用自定义 bridge 网络(
docker network create mynet),并用容器名(如redis)直连,跳过docker0
避免 client-output-buffer-limit 触顶导致断连
每个 pubsub 连接独占输出缓冲区,而默认配置 client-output-buffer-limit pubsub 32mb 8mb 60 在高频多频道场景下极易溢出,触发强制断连 —— 此时延迟不再是网络问题,而是连接重建耗时(通常 >10ms)。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 线上启动 30+ Python 订阅线程时,务必为每个线程分配独立
redis.Redis()实例和pubsub对象 - 订阅不同 channel(如
trade:0~trade:29),避免单 channel 内部广播锁竞争 - 在
listen()循环中禁止做任何阻塞操作:DB 写入、HTTP 请求、日志刷盘等,否则消息积压撑爆缓冲区 - 建议将
client-output-buffer-limit pubsub调大(如256mb 64mb 300),并监控redis-cli --stat中的output_buffer字段
别用 redis-benchmark 压测 PUB/SUB
redis-benchmark -t pubsub 只建单个发布 + 单个订阅连接,反复循环收发,完全脱离真实交易场景:它不创建多 TCP 连接、不触发缓冲区溢出、不模拟多频道分发压力,跑出的 “80w+ ops/s” 数值毫无参考价值。
- 真实压测必须用多线程/多进程脚本,每个线程持有一个独立
redis.Redis()实例 - 发布者用
PUBLISH,订阅者用SUBSCRIBE(非PSUBSCRIBE,模式匹配有额外开销) - 测量延迟应取客户端时间戳差值:
publish_ts → receive_ts,而非 Redis 服务端日志 - Redis 8.2.3 已修复 CVE-2025-62507 等高危漏洞,建议升级,避免因安全补丁引入意外延迟抖动
真正卡住“最后 100 微秒”的,往往不是 Redis 配置,而是客户端线程调度、TCP Nagle 算法、以及内核 softirq 处理顺序——这些已超出 Redis 自身控制范围,需结合 perf 和 tcpdump 进一步定位。










