我正在编写一个部署脚本,它将我的代码打包成一个目录,以当前日期和时间命名该 tar 文件,将其推送到服务器,在同名目录中解压,然后交换“当前”符号链接以指向新目录。这意味着我的旧部署会保留在带时间戳的目录中(至少在我删除它们之前)。
tar 文件大约 5MB,传输需要将近一分钟。我想加快速度。
我假设每个新的 tarball 在结构上都与之前的 tarball 非常相似(因为我在部署之间通常只更改几行源代码)。有没有办法利用这个事实来加快使用 rsync 的上传速度?
理想情况下,我想说“嘿 rsync,将这个名为 2009-10-28-222403.tar.gz 的本地文件上传到我的服务器,但它与已经存在的文件 2009-10-27-101155.tar.gz 只有一点点不同,所以尝试只发送不同部分”。这可能吗,还是我应该查看其他工具?
答案1
我正在整理一个部署脚本,将我的代码打包成一个目录,根据当前日期和时间命名该 tar 文件,将其推送到服务器,在同名目录中解压它,然后交换“当前”符号链接以指向新目录。
我个人认为你应该跳过使用 tar,而是考虑使用 --link-dest 或 --copy-dest 功能同步。link-dest 函数非常酷,它会知道查看目录的先前同步,并且如果文件相同,它会将它们硬链接在一起,从而无需每次重新传输文件。
mkdir -p /srv/codebackup/2009-10-12 \
/srv/codebackup/2009-10-13
# first backup on 10-12
rsync -a sourcehost:/sourcepath/ \
/srv/codebackup/2009-10-12/
# second backup made on 10-13
rsync -a --link-dest=/srv/codebackup/2009-10-12/
sourcehost:/sourcepath/ \
/srv/codebackup/2009-10-13/
第二次运行 rsync 将仅传输已更改的文件。相同的文件将硬链接在一起。您可以删除旧树,而新备份仍将 100% 完整。您将节省大量存储空间,因为您不会保留相同文件的多个副本。
答案2
据我所知,rsync 无法直接执行此操作,但您可以构造您的 tarball 以使它们传输得更快,利用它们相似的事实。
查看 gzip 的 --resyncable 标志。摘自手册:
压缩时,偶尔根据输入同步输出。大多数情况下,这会使文件大小增加不到 1%,但这意味着 rsync(1) 程序可以更有效地同步使用此标志压缩的文件。 gunzip 无法区分使用此选项创建的压缩文件和未使用此选项创建的压缩文件。
这将使您的类似 tarball 实际上更加相似,以便 rsync 能够识别它们。
您可能需要稍微修改一下部署脚本以减少传输量,因为我认为不能让 rsync “查看另一个文件”……我所做的始终是 rsync 名为 current.tar.gz 的文件(使用 gzip 和上述标志压缩),然后将其重命名以便在服务器上存档。或者将服务器上的旧 tarball 重命名为即将上传的 tarball 的名称,以便 rsync 可以使用它。
答案3
我认为在这里使用 tar 是错误的答案。对于这种特殊情况,我会做的是,cp -rp 将服务器上的“当前”代码复制到过时的目录中。然后 rsync 将您的本地代码签出到“当前”。所以基本上是这样的:
ssh 用户@主机 cp -rp /路径/到/当前 /路径/到/2009-10-28/
rsync /本地/复制用户@主机名:/路径/到/当前路径
这会为您提供所需的备份副本,同步您的更改,并且比 tar+scp+untar 快得多。
希望有帮助!
答案4
您可以查看 rsync 的模糊模式(通过--fuzzy
开关激活)
这样 rsync 就可以选择目标系统上与要传输的文件相似的文件,并使用该文件作为应用增量上传算法的基础。这会占用一些内存和 I/O,特别是如果目标端有一个大目录,但它应该可以为您提供所需的上传改进,而无需像其他答案建议的那样重新调整方法。