我们使用 rsync 将主文件服务器的镜像更新到异地共置备份服务器。我们目前遇到的问题之一是,我们的文件服务器有超过 1TB 的文件,其中大部分都是较小的文件(在 10-100kb 范围内),当我们传输这么多数据时,我们经常会在传输几个小时后断开连接。Rsync 没有恢复/重试功能,该功能只能重新连接到服务器以从中断的地方继续传输 - 您需要完成文件比较过程,而由于我们拥有的文件数量众多,这个过程最终会变得非常冗长。
建议的解决方案是将大型 rsync 传输拆分为一系列较小的传输。我认为最好的方法是使用顶级目录名称的首字母,虽然这不能给我们一个完全均匀的分布,但已经足够好了。
我想确认我这样做的方法是否合理,或者是否有更简单的方法来实现目标。
为此,我遍历 AZ、az、0-9 来选择一个字符$prefix
。最初我只想运行
rsync -av --delete --delete-excluded --exclude "*.mp3" "src/$prefix*" dest/
(--exclude“*.mp3” 只是一个例子,因为我们有一个更长的排除列表来删除临时文件之类的东西)
问题在于,dest/ 中不再存在于 src 上的任何顶级目录都不会被 --delete 拾取。为了解决这个问题,我尝试了以下方法:
rsync \
--filter 'S /$prefix*' \
--filter 'R /$prefix*' \
--filter 'H /*' \
--filter 'P /*' \
-av --delete --delete-excluded --exclude "*.mp3" src/ dest/
我使用show
andhide
而不是include
and exclude
,因为否则 --delete-excluded 将删除任何与 $prefix 不匹配的内容。
这是将 rsync 拆分成较小块的最有效方法吗?是否有更有效的工具或我错过的标志可以使这更简单?
答案1
我的解决方案是采用不同的两遍方法,其中我牺牲了一些磁盘空间。我在服务器上执行 rsync --only-write-batch,然后将批处理文件本身 rsync 到目标,循环直到 rsync 成功。批处理完全结束后,目标上的 rsync --read-batch 将重新创建所有更改。
这对我来说也有一些意想不到的好处:
因为我更关心备份“存在”而不是“可用”,所以我实际上并不是每天都在接收端执行读取批处理——大多数时候批处理相对较小
我一直在尝试使用--checksum-seed = 1 ...我可能误读了文档,但我认为它使批处理文件更可同步(即当我在任何一天不执行--read-batch时,第二天的批次同步速度更快,因为前一天批次是一个很好的基础)
如果批处理太大而无法通过互联网“及时”发送,我可以通过外部驱动器偷偷将其发送。所谓及时,是指如果我无法在第二天的备份开始之前将批处理发送过来并读取。
虽然我个人不这样做,但我可以在不同的位置进行两次异地备份,并将批次发送给它们两个。
答案2
这并不完全回答您的问题,但我经常使用的另一种选择是通过两遍方法执行此操作:首先构建文件列表,然后拆分要传输的文件列表并将文件列表输入到 rsync/cpio/cp 等中。
rsync --itemize-changes <rest of options>
将打印出要传输的文件列表以及一堆有用的元数据,从该输出中可以很容易地提取文件名,然后使用其中一个rsync --files-from
工具或其他工具进行实际复制。
可能对您的情况有用 - 从中断的传输中恢复会更快。
答案3
我建议您密切关注连接问题,而不是试图通过创建另一个“问题”来解决它。
这不是常见行为。您是通过 SSH 还是 rsyncd 使用 rsync?
据我所知,大多数“关闭”连接都是在端点之间没有数据传输时发生的。