背景
我有一台托管虚拟机的服务器和一台较旧的 NAS Synology DS1512+,用作这些虚拟机的备份目标。服务器使用 ZFS,创建快照并将快照文件传输到 NAS。NAS 使用启用了压缩的 BTRFS,并且也支持快照。最终目标是服务器实际上只使用 RSYNC 发送 DELTA,以最大限度地减少 NAS 收到的更改数据量,并有效利用快照。
问题
不过,在我的例子中,使用 RSYNC 和 DELTA 不起作用,因为传输数据只需要太多时间。当 RSYNC 与 一起使用时--inplace --whole-file
,数据传输需要大约 2 小时。当删除--whole-file
以使用 DELTA 时,相同的备份过程需要更长的时间,我经常在运行 12 多个小时后终止该过程。由于历史原因,我需要将不同的备份放入更小的时间窗口中。
唯一有意义的瓶颈是 NAS,因为服务器功能强大得多,并且大多数时间都处于空闲状态。另一方面,NAS 在备份期间的 CPU 和 I/O 负载相当高。不过,这些数字也不算太糟糕,只是比使用时更糟糕--whole-file
。这样一来,NAS 的写入速度基本上只是 ~100+ MiB/s,而使用 DELTA 时,它大多数时间的读取速度较慢,范围从 ~50 到 100 MiB/s。我认为由于 DELTA 而不需要写入的数据量很容易超过 NAS 速度较慢的事实,但事实似乎并非如此。并且虚拟机上更改的数据量大多数情况下并不太高。
观察
我在 NAS 上发现,RSYNC 似乎在某个时刻同时处理两个文件。这看起来像是预读或类似操作:
root@amds1512-01:~# lsof | grep [d]asi_
rsync 6883 root cwd DIR 0,33 290 259 /volume1/[...]
rsync 6883 root 0r REG 0,33 2142633984 580 /volume1/[...]/[...]-s024.vmdk
rsync 6884 root cwd DIR 0,33 290 259 /volume1/[...]
rsync 6884 root 1r REG 0,33 2143748096 579 /volume1/[...]/[...]-s023.vmdk
rsync 6884 root 3w REG 0,33 2143748096 579 /volume1/[...]/[...]-s023.vmdk
HTOP 清楚地显示两个 RSYNC 实例都执行了读取操作。只需忽略其他 RSYNC 进程,它们无关,即使只运行一个备份,问题仍然存在。
问题
那么,这两个在备份目标上运行不同文件的 RSYNC 的目的是什么?有没有办法告诉 RSYNC 只处理一个接一个的文件?
这可能会增加总体处理时间,同时减少并发负载。我在手册页中找不到任何类似预读或类似的东西。如果有什么不同,以下是使用的选项:
--owner \
--numeric-ids \
--compress-level=0 \
--group \
--perms \
--rsh=rsh \
--devices \
--hard-links \
--inplace \
--links \
--recursive \
--times \
--delete \
--delete-during \
--delete-excluded \
--rsync-path=[...] \
--specials
谢谢!
答案1
看一眼Rsync 的工作原理具体来说,有一个生成器进程和一个发送器进程,它们以管道的方式运行。发送器读取要发送到远程的文件。生成器负责生成要发送的文件列表,并且“为基础文件创建块校验和,并在文件索引号之后立即发送给发送器。”
--inplace
如果你使用这个命令发送多个大文件,这听起来确实有可能导致文件系统崩溃并且没有足够的 RAM 供内核在缓存中保存两个连续的文件。
作为测试,您可以尝试使用 传输单个文件,rsync --inpace
看看性能是否明显更好。(类似于for i in *.vmdk; do rsync [...]; done
。)这应该有助于确定是否有两个单独的读取器实际上导致了您的性能问题。
如果有多位读者是导致性能问题,那么一个可能的方法是提高内核缓存读取的能力,要么为主机内核提供更多的RAM,要么使各个vmdk文件更小。
不幸的是,除了编写自己的脚本为每个文件调用一次 rsync 之外,我找不到任何明显的方式来改变 rsync 中的生成器/发送器管道行为。您可能想在rsync 邮件列表。