小文件在 VPN 上变慢,是因为往返次数,而不是速度
一堆小文件要付大文件可以掩盖的元数据和往返成本。在责怪隧道带宽之前,先测量工作负载的形态。
通过 VPN 复制一个 2 GB 的文件,传输看起来没问题。复制一个装着一万份小文档的文件夹,同一条链路却像坏了一样。差别不是两次任务之间改过的带宽设置。第二项任务把时间花在建立连接、元数据和等待响应上,而正是隧道的延迟让这种等待变得可见。
单个文件是流式的,文件夹则要协商
大文件的复制大部分时间都花在少数几个打开句柄上的读写循环里。协议开销每个文件只付一次,数据以大块传输。带宽决定了结果。
文件夹复制要为每个文件付费:创建、查询属性、打开、写入、关闭以及更新目录元数据。其中每一项都是一次请求,都要等回应之后下一步才能继续。字节很小,协调却不是。
所以一张链路利用率很低的图几乎证明不了什么。链路空着,是因为客户端在等,而不是因为隧道慢。存储阵列或终端扫描器也可能加上同样的延迟形状。在改动任何网络设置之前,先弄清是哪一个阶段在等待。
往返次数累积得比字节快
延迟就是一次依赖型交换的代价。如果一个文件需要几次串行交换,而隧道每程增加 40 ms,那么单个文件的成本就会迅速上升。一万个文件就把它变成了几分钟。
这个算术只是示例,不是基准:一个文件不一定只花一次往返,客户端也会重叠一部分工作。
两个杠杆改变总量。减少每个文件的依赖型交换次数,或者让更多交换同时在途。前者是协议或工作负载的改动,后者是并发。两者都不能让慢链路变快。
测量工作负载,而不是链路
用相同的端点和相同的访问策略比较三项任务:一个大文件、小文件文件夹,以及实际的业务操作。每次结果都要记录文件数量、大小分布、复制工具和网络条件。
只有单个 MB/s 数字、没有这些细节,就无法与任何人的结果比较。
把延迟和吞吐分开测量。对文件服务器做一次简单的往返测试,就得到会乘到许多小操作上的那个数字。然后观察复制的请求模式,而不是平均速率。如果速率低而链路空着,瓶颈就在隧道之上。
改变任务:并发与归档
对于获准的批量复制,能控制并发的工具可以让更多请求同时在途。Robocopy 的 /MT 选项是 Windows 上常见的例子。增加线程并不保证复制更快。
选一个客户端、服务器和存储都能承受的数量,并保留下作业日志和任何错误。
在源端归档、在本地解包,就消除了每个文件的远程工作。比较时要把准备和解包的时间算进去,并确认归档保留了任务所需的元数据和权限。这两个办法都不会让应用程序把自己的文件操作合并成批。
用受控测试检查计数器
只改一个变量,把同一项任务跑两遍,并记录两个数字。只有受控测试才能知道是某个设置起了作用,还是网络恰好更安静。
两条命令给出文件数量和往返基线:
Get-ChildItem \\fileserver.hq.example\\share -Recurse | Measure-Object -Property Length -Sum
ping -n 20 fileserver.hq.example
然后用受限的线程数运行复制,并把日志与上一次运行对比:
robocopy \\fileserver.hq.example\\share C:\\local /E /MT:16 /LOG:copy.log /TEE
不要为了改善计数而关闭 SMB 签名、加密或终端保护。那些改动是拿一项安全属性去换一个也许并非瓶颈的数字。并且在笔记里把 VPN 传输与 SMB 自身的传输分开,因为对其中一个的修复并不能证明另一个。