![如何在机器之间同步巨大的稀疏文件(VM 磁盘映像)?](https://linux22.com/image/493848/%E5%A6%82%E4%BD%95%E5%9C%A8%E6%9C%BA%E5%99%A8%E4%B9%8B%E9%97%B4%E5%90%8C%E6%AD%A5%E5%B7%A8%E5%A4%A7%E7%9A%84%E7%A8%80%E7%96%8F%E6%96%87%E4%BB%B6%EF%BC%88VM%20%E7%A3%81%E7%9B%98%E6%98%A0%E5%83%8F%EF%BC%89%EF%BC%9F.png)
是否有一个命令,例如 rsync,可以将巨大的、稀疏的文件从一台 Linux 服务器同步到另一台?
目标文件保持稀疏非常重要。它可能比包含它的驱动器更长(但不更大)。只有更改的块才应通过网络发送。
我尝试过 rsync,但是没有任何效果。https://groups.google.com/forum/#!topic/mailing.unix.rsync/lPOScZgFE9M
如果我编写一个程序来实现这一点,那我是不是又在重新发明轮子了? http://www.finalcog.com/synchronise-block-devices
谢谢,
克里斯。
答案1
rsync --ignore-existing --sparse ...
以稀疏模式创建新文件
其次是
rsync --inplace ...
就地更新所有现有文件(包括先前创建的稀疏文件)。
答案2
要同步具有较低到中等差异的大型文件或块设备,您可以执行普通复制或使用同步,rsync 绝对不适合这种特殊情况*。
bdsync
对我来说很管用,似乎足够成熟,它的 bug 历史记录令人鼓舞(小问题,快速解决)。在我的测试中,它的速度接近理论上的最大速度**(也就是说,您可以在读取文件所需的时间内同步)。最后,它是开源的,而且不收费。
bdsync
读取来自两台主机的文件并交换校验和以进行比较并检测差异。所有这些同时。它最终在源主机上创建一个压缩的补丁文件。然后您将该文件移动到目标主机并再次运行 bdsync 来修补目标文件。
当通过较快的链接(例如 100Mbit 以太网)使用它时,对于差异较小的文件(在 VM 磁盘上最常见),它会将同步时间缩短到读取文件所需的时间。通过较慢的链接,您需要更多时间,因为您必须将压缩的更改从一台主机复制到另一台主机(似乎您可以使用以下方法节省时间一个不错的技巧但还没有测试过)。对于有许多更改的文件,还应考虑将补丁文件写入磁盘的时间(并且您需要在两个主机中都有足够的可用空间来保存它)。
以下是我通常使用 bdsync 的方式。这些命令在 上运行$LOCAL_HOST
以“复制”$LOCAL_FILE
到$REMOTE_FILE
上$REMOTE_HOST
。我使用pigz
(更快的gzip
)来压缩更改,ssh
在远程主机上运行 bdsync 和rsync
/ssh
来复制更改。请注意,我正在检查补丁是否已成功应用,但只有在成功应用时我才会打印“更新成功”。如果失败,您可能希望采取更高级的措施。
REMOTE_HOST=1.2.3.4
LOCAL_FILE=/path/to/source/file
REMOTE_FILE=/path/to/destination/file
PATCH=a_file_name
LOC_TMPDIR=/tmp/
REM_TMPDIR=/tmp/
# if you do use /tmp/ make sure it fits large patch files
# find changes and create a compressed patch file
bdsync "ssh $REMOTE_HOST bdsync --server" "$LOCAL_FILE" "$REMOTE_FILE" --diffsize=resize | pigz > "$LOC_TMPDIR/$PATCH"
# move patch file to remote host
rsync "$LOC_TMPDIR/$PATCH" $REMOTE_HOST:$REM_TMPDIR/$PATCH
# apply patch to remote file
(
ssh -T $REMOTE_HOST <<ENDSSH
pigz -d < $REM_TMPDIR/$PATCH | bdsync --patch="$REMOTE_FILE" --diffsize=resize && echo "ALL-DONE"
rm $REM_TMPDIR/$PATCH
ENDSSH
) | grep -q "ALL-DONE" && echo "Update succesful" && rm "$LOC_TMPDIR/$PATCH"
# (optional) update remote file timestamp to match local file
MTIME=`stat "$LOCAL_$FILE" -c %Y`
ssh $REMOTE_HOST touch -c -d @"$MTIME_0" "$REMOTE_FILE" </dev/null
*:rsync 在处理大型文件时效率极低。即使使用 --inplace,它也会先读取目标主机上的整个文件,然后开始读取源主机上的文件,最后传输差异(只需在运行 rsync 时运行 dstat 或类似程序并观察)。结果是,即使对于差异较小的文件,读取文件以同步所需的时间也大约是所需时间的两倍。
**:假设您没有其他方法可以判断文件的哪些部分已更改。LVM 快照使用位图来记录已更改的块,因此它们的速度非常快(自述文件lvm同步有更多信息)。
答案3
Rsync 仅传输对每个文件的更改,并使用 --inplace 仅重写已更改的块,而无需重新创建文件。从他们的功能页面。
rsync 是 Unix 系统的一个文件传输程序。rsync 使用“rsync 算法”,该算法提供了一种非常快速的方法使远程文件同步。它通过仅发送文件中的差异来实现此目的,而无需事先在链接的一端存在两组文件。
使用 --inplace 应该对你有用。这将显示进度、压缩传输(在默认压缩级别)、递归传输本地存储目录的内容(第一个尾部斜杠很重要)、对文件进行更改并使用 ssh 进行传输。
rsync -v -z -r --inplace --progress -e ssh /path/to/local/storage/ \
[email protected]:/path/to/remote/storage/
我也经常使用 -a 标志,它可以做更多的事情。它相当于 -rlptgoD,我将把确切的行为留给您查看手册页。
答案4
我最终编写了软件来实现这一点:
这是商业软件,每台物理服务器的成本为 49 美元。
我现在可以在 3 分钟内通过住宅宽带复制一个 50GB 的稀疏文件(其中包含 3GB 的内容)。
chris@server:~$ time virtsync -v /var/lib/libvirt/images/vsws.img backup.barricane.com:/home/chris/
syncing /var/lib/libvirt/images/vsws.img to backup.barricane.com:/home/chris/vsws.img (dot = 1 GiB)
[........>.........................................]
done - 53687091200 bytes compared, 4096 bytes transferred.
real 2m47.201s
user 0m48.821s
sys 0m43.915s