管道越大越快吗?这篇把批量大小从 1 一路加到 10 万,量吞吐的曲线;再量批量过大的两笔代价:服务器为这个客户端缓冲的输出、以及对同时连着的其它客户端延迟的影响。
批量 条/秒
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 另一个客户端 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 MBN = 10 万条 1 KB 的 GET 时,服务器为这个客户端缓冲了 36 MB 输出;N = 100 万时 914 MB——因为客户端还在发、没开始读,回复全部堆在服务器的客户端输出缓冲区里(第 113 篇讨论这个缓冲区的上限)。对其它客户端的影响这里不算大(7.3 ms 的最大停顿),但这个管道自己要 805 ms。
把批量控制在几百到几千条,边发边读回复(而不是发完再读);超大批量既拿不到更多吞吐,又要占用服务器内存。这条建议基于上面的曲线(1000 以后趋平)和缓冲区数据;具体拐点取决于命令大小和 RTT。