bigywater.tech
Redis · 103

Redis Pipeline 批量大小

管道越大越快吗?这篇把批量大小从 1 一路加到 10 万,量吞吐的曲线;再量批量过大的两笔代价:服务器为这个客户端缓冲的输出、以及对同时连着的其它客户端延迟的影响。

39k → 620k
批量 1 → 1000 的吞吐(条/秒);1000 之后趋平
914 MB
一次发 100 万条 GET(1 KB)时服务器为该客户端缓冲的输出
7.3 ms
此时另一个客户端 PING 的最大停顿

吞吐曲线

实测 · 本机执行输出
      批量        条/秒
       1      39354
       2      67352
       5     138116
      10     216792
      50     429893
     100     517513
     500     587285
    1000     620459
    5000     736441
   20000     771920
  100000     752464

吞吐随批量迅速上升:批量 1 → 10 涨 5.5 倍,10 → 100 涨 2.4 倍,100 → 1000 只涨 1.20 倍,1000 之后基本持平(772k、752k)。这是本机回环上的曲线;RTT 大时(第 102 篇)曲线的拐点会推后,但趋平的地方仍然是服务器处理能力的上限。

批量太大的代价

一个客户端先把 N 条命令全部发出去、再读回复(最朴素的写法)
实测 · 本机执行输出
       N       另一个客户端 PING 最大停顿       完成耗时   peak 输出缓冲(client_recent_max_output_buffer)
    1000                 0.7 ms        3 ms                                  3.4 MB
   10000                 0.7 ms       10 ms                                  3.4 MB
  100000                 4.2 ms       80 ms                                 36.0 MB
 1000000                 7.3 ms      805 ms                                914.1 MB

N = 10 万条 1 KB 的 GET 时,服务器为这个客户端缓冲了 36 MB 输出;N = 100 万时 914 MB——因为客户端还在发、没开始读,回复全部堆在服务器的客户端输出缓冲区里(第 113 篇讨论这个缓冲区的上限)。对其它客户端的影响这里不算大(7.3 ms 的最大停顿),但这个管道自己要 805 ms。

建议

把批量控制在几百到几千条,边发边读回复(而不是发完再读);超大批量既拿不到更多吞吐,又要占用服务器内存。这条建议基于上面的曲线(1000 以后趋平)和缓冲区数据;具体拐点取决于命令大小和 RTT。

分步演示:批量大小

Pipeline 批量大小
本步的数据

    本文用到的工具与边界

    • 本机 macOS 27 / Redis 8.10.2 独立实例(本机回环端口,save 关闭),redis-cli 风格输出由自写的 RESP 客户端打印;计时用 time.perf_counter,数字每次运行会有小幅抖动。GET 100 字节 value 的吞吐每格 3 次取中位;大管道实验用 1 KB value,客户端发完再读,另一个客户端每 1 ms PING
    • 没有验证:边发边读的流水线写法的缓冲区占用、多个大管道并发、SET/写命令的批量曲线、开启 io-threads 后的曲线(第 109 篇)
    京ICP备2026067502号-1京公网安备11010502063487号