几天前,我注意到一件相当奇怪的事情(至少对我来说)。我运行 rsync 复制相同的数据,然后将其删除到名为 的 NFS 挂载点/nfs_mount/TEST
。它/nfs_mount/TEST
托管/导出自nfs_server-eth1
。两个网络接口上的 MTU 都是 9000,中间的交换机也支持巨型帧。如果我这样做,rsync -av dir /nfs_mount/TEST/
我的网络传输速度将达到 X MBps。如果我这样做,rsync -av dir nfs_server-eth1:/nfs_mount/TEST/
我的网络传输速度将至少达到 2X MBps。我的 NFS 挂载选项是nfs rw,nodev,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountvers=3,mountproto=tcp
。
底线:两种传输都通过相同的网络子网、相同的线路、相同的接口、读取相同的数据、写入相同的目录等。唯一的区别是一个是通过 NFSv3,另一个是通过 rsync。
客户端是Ubuntu 10.04,服务器是Ubuntu 9.10。
rsync 怎么会这么快?如何让 NFS 达到这样的速度?
谢谢
编辑:请注意,我使用 rsync 写入 NFS 共享或通过 SSH 进入 NFS 服务器并在那里进行本地写入。两次我都这样做rsync -av
,从清除目标目录开始。明天我将尝试使用纯文本副本。
编辑 2(附加信息):文件大小范围为 1KB-15MB。文件已经压缩,我尝试进一步压缩它们,但没有成功。我tar.gz
从中创建了文件dir
。以下是模式:
rsync -av dir /nfs_mount/TEST/
= 最慢的传输;rsync -av dir nfs_server-eth1:/nfs_mount/TEST/
= 启用巨型帧时速度最快;没有巨型帧时速度会慢一点,但仍然比直接到 NFS 的速度快得多;rsync -av dir.tar.gz nfs_server-eth1:/nfs_mount/TEST/
= 与非 tar.gz 版本大致相同;
cp
使用和进行测试scp
:
cp -r dir /nfs_mount/TEST/
= 比 稍快rsync -av dir /nfs_mount/TEST/
但仍然比 慢得多rsync -av dir nfs_server-eth1:/nfs_mount/TEST/
。scp -r dir /nfs_mount/TEST/
= 总体最快,略微克服rsync -av dir nfs_server-eth1:/nfs_mount/TEST/
;scp -r dir.tar.gz /nfs_mount/TEST/
= 与非 tar.gz 版本大致相同;
根据结果得出的结论:对于此测试,使用 tar.gz 大文件或多个小文件没有显著差异。打开或关闭巨型帧也几乎没有区别。cp
并且scp
比它们各自的rsync -av
等效项更快。无论使用哪种方法,直接写入导出的 NFS 共享都比通过 SSH 写入同一目录慢得多(至少 2 倍)。
cp
在这种情况下,和之间的差异rsync
并不重要。我决定尝试cp
看看scp
它们是否显示出相同的模式,结果确实如此 - 差异为 2 倍。
由于我在两种情况下都使用rsync
或cp
,我不明白是什么阻止 NFS 达到通过 SSH 执行相同命令的传输速度。
为什么写入 NFS 共享比通过 SSH 写入同一位置慢 2 倍?
编辑3(NFS 服务器 /etc/exports 选项):。rw,no_root_squash,no_subtree_check,sync
客户端的 /proc/mounts 显示:nfs rw,nodev,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountvers=3,mountproto=tcp
。
谢谢你们!
答案1
也许不是传输速度变慢,而是写入延迟增加。尝试以异步方式而不是同步方式挂载 NFS 共享,看看是否能缩小速度差距。当您通过 ssh 进行 rsync 时,远程 rsync 进程会异步(快速)写入。但是,当写入同步挂载的 nfs 共享时,写入不会立即确认:NFS 服务器会等到写入磁盘(或更可能是控制器缓存)后才向 NFS 客户端发送写入成功的确认。
如果“异步”解决了您的问题,请注意,如果 NFS 服务器在写入过程中发生某些事情,您很可能会得到磁盘上不一致的数据。只要此 NFS 挂载不是此数据(或任何其他数据)的主要存储,您可能就不会有事。当然,如果您在 rsync-over-ssh 运行期间/之后拔掉 nfs 服务器的插头,您也会遇到同样的情况(例如 rsync 返回“完成”,nfs 服务器崩溃,写入缓存中未提交的数据现在丢失,导致磁盘上的数据不一致)。
虽然您的测试(rsyncing 新数据)没有问题,但请注意,在计算校验和并生成需要更新的文件列表之前,通过 ssh 进行的 rsync 会在传输单个字节之前对远程服务器产生大量的 CPU 和 IO 需求。
答案2
NFS 是一种共享协议,而 Rsync 针对文件传输进行了优化;当你了解时,可以进行很多优化先验您的目标是尽快复制文件,而不是提供对它们的共享访问。
答案3
Rsync 是一种文件协议,它只在文件之间传输更改的位。NFS 是一种远程目录文件协议,每次都会处理所有内容……在某种程度上有点像 SMB。两者不同,用途也不同。您可以使用 Rsync 在两个 NFS 共享之间进行传输。
答案4
如果您的目标是将所有文件从一个地方复制到另一个地方,那么 tar/netcat 将是最快的选择。如果您知道文件中有很多空格(零),那么请使用 -i 选项。
来源:tar cvif - /path/to/source | nc 目标 PORTNUM 目标:cd /path/to/source && nc -l PORTNUM | tar xvif -
如果你知道你的数据是可压缩的,那么在 tar 命令上使用压缩 -z -j -Ipixz
我是 pixz .. parallel xz 的粉丝,它提供了很好的压缩率,而且我可以根据网络带宽调整 CPU 的数量。如果我的带宽较慢,我会使用更高的压缩率,因此我等待 CPU 的时间比等待网络的时间要多。如果我的网络很快,我会使用非常低的压缩率:
源:tar cvif - /path/to/source | pixz -2 -p12 | nc 目标端口号# tar,忽略零,使用 12 个 CPU 核心进行 2 级 pixz 压缩 目标:nc -l 端口号 | tar -Ipixz -xvif
如果您根据数据集正确调整压缩级别和核心,您应该能够使网络接近饱和,并进行足够的压缩,瓶颈就会变成磁盘(如果读写磁盘系统相同,则通常是写入端)。
至于 rsync,我相信它跳过零的方式与 tar 使用该选项的方式类似,因此它传输的数据比 NFS 少。NFS 无法对数据做出假设,因此必须传输每个字节以及 NFS 协议开销。rsync 有一些开销。
netcat 基本上没有...它会发送完整的 TCP 数据包,其中只包含您关心的数据。
使用 netcat 时,与 scp 一样,您必须始终发送所有源数据,而不能像使用 rsync 那样进行选择,因此它不适合增量备份或诸如此类的事情,但它适合复制数据或存档。