在本地复制大型目录树?cp 还是 rsync?

Ama*_*rus 308 linux unix files rsync file-transfer

我必须复制一个大目录树,大约 1.8 TB。都是本地的。出于习惯,我会使用rsync,但是我想知道是否有很多意义,以及我是否应该使用cp.

我担心权限和 uid/gid,因为它们必须保留在副本中(我知道 rsync 会这样做)。以及符号链接之类的东西。

目的地是空的,所以我不必担心有条件地更新一些文件。都是本地磁盘,所以不用担心ssh或网络。

我不想使用 rsync 的原因是因为 rsync 可能做的比我需要的多。rsync 校验和文件。我不需要那个,我担心它可能需要比 cp 更长的时间。

那你怎么看,rsync或者cp

Ham*_*ner 247

我会使用 rsync,因为这意味着如果它因任何原因被中断,那么您可以以很少的成本轻松地重新启动它。作为 rsync,它甚至可以通过一个大文件部分重启。正如其他人提到的,它可以轻松排除文件。保存大多数东西的最简单方法是使用-a标志——“归档”。所以:

rsync -a source dest
Run Code Online (Sandbox Code Playgroud)

尽管 UID/GID 和符号链接由-a(请参阅-lpgo)保留,但您的问题暗示您可能需要文件系统信息的完整副本;并且-a不包括硬链接、扩展属性或 ACL(在 Linux 上)或以上内容,也不包括资源派生(在 OS X 上)。因此,对于文件系统的健壮副本,您需要包括这些标志:

rsync -aHAX source dest # Linux
rsync -aHE source dest  # OS X
Run Code Online (Sandbox Code Playgroud)

默认 cp 将再次启动,尽管该-u标志将“仅在源文件比目标文件新或目标文件丢失时才复制”-a如果您必须重新启动并保留权限,(归档)标志将是递归的,而不是重新复制文件。所以:

cp -au source dest
Run Code Online (Sandbox Code Playgroud)

  • 和 --progress 这真的很方便! (29认同)
  • -P 或 --progress 分别显示每个文件的进度。它对于复制大文件很有用,而不是对于许多(数千个)小文件,因为这意味着您无法读取更多的输出。它不显示所有文件组合的总体进度。 (18认同)
  • 实际上,rsync 检测本地传输并启用整个文件复制,而无需自动校验和。 (13认同)
  • @SPRBRN 从 rsync 3.1.0 版开始,它支持 `rsync --info=progress2`,它确实显示了传输的整体进度(尽其所能)。用于在大型传输期间提供近似值。 (12认同)
  • cp 的 -u 标志可能不是最好的解决方案,因为它不会检测到部分复制/损坏的文件。rsync 的好处是你可以让它 md5 总结文件以检测差异。 (5认同)
  • 添加 -w (--whole-file) 选项将加速中断的 rsync,因为它只会复制文件而不是校验和。 (3认同)
  • 我想你想要`rsync -aHAX -vx src dst`。`H` 保留硬链接,`A` 复制 ACL,`X` 复制扩展属性。`-vx` 是可选的,但它会打印它正在做什么(`v`)并限制为一个文件系统(`x`)。 (2认同)

Ell*_*val 166

复制到本地文件系统时,我倾向于使用带有以下选项的 rsync:

# rsync -avhW --no-compress --progress /src/ /dst/
Run Code Online (Sandbox Code Playgroud)

这是我的推理:

-a is for archive, which preserves ownership, permissions etc.
-v is for verbose, so I can see what's happening (optional)
-h is for human-readable, so the transfer rate and file sizes are easier to read (optional)
-W is for copying whole files only, without delta-xfer algorithm which should reduce CPU load
--no-compress as there's no lack of bandwidth between local devices
--progress so I can see the progress of large files (optional)
Run Code Online (Sandbox Code Playgroud)

正如另一个答案所建议的那样,我已经看到通过以下 tar 命令使用上述 rsync 设置的传输速度提高了 17%:

# (cd /src; tar cf - .) | (cd /dst; tar xpf -)
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个选项,但如果运行大型目录树,进度可能无法读取。使用“--info=progress2”而不是“--progress”将进度信息保留为单个更新行。 (4认同)
  • 像@alper 一样,--no-compress 不是我的 rsync 版本(在 CentOS 7 中)的选项;我改用 --compress-level=0 。 (3认同)
  • 我遇到以下错误:`rsync: --no-compress: unknown option` @Ellis Percival。 (2认同)

Cha*_*utt 83

当我必须复制大量数据时,我通常会使用 tar 和 rsync 的组合。第一遍是对它进行 tar 处理,如下所示:

# (cd /src; tar cf - .) | (cd /dst; tar xpf -)
Run Code Online (Sandbox Code Playgroud)

通常对于大量文件,会有一些 tar 因任何原因无法处理。或者该过程可能会中断,或者如果它是文件系统迁移,您可能希望在实际迁移步骤之前进行初始复制。无论如何,在初始复制之后,我执行了一个 rsync 步骤来同步它:

# cd /dst; rsync -avPHSx --delete /src/ .
Run Code Online (Sandbox Code Playgroud)

请注意,尾部斜杠/src/很重要。

  • 这就是这种方法的美妙之处。您不需要双倍空间,因为您实际上从未创建过中间 tar 文件。管道前的 tar 将数据打包并将其流式传输到 stdout,管道后的 tar 从 stdin 中获取数据并解包。 (20认同)
  • +1 我发现 tar 对于大副本通常比 rsync 更快。我也喜欢用最后的 rsync 来结束这个想法。 (7认同)
  • 我为 12gb 传输做了一个 cp -a,而这个方法用于 42gb 传输。tar 方法花费了大约 1/4 的时间。 (5认同)
  • 我还将 `pv` 放在中间以便能够观察进度,使用 `df` 估计所有数据的大小。我还使用了 `--numeric-owner`,因为源磁盘来自另一个系统,我不希望 `tar` 弄乱所有者:`tar -C /old-path --numeric-owner -S -c . | pv -tpeba -s 100G | tar -C /new-path --numeric-owner -S -xp` (4认同)
  • 不需要子shell:`tar -C /src -c 。| tar -C /dst -xp` (3认同)
  • 如果 dest 目录为空,则 tar 是一个不错的选择。虽然我的方式是: cd $DSTDIR; 焦油 c -C $SRCDIR 。| 柏油 (2认同)

小智 16

同步

这是我使用的 rsync,我更喜欢 cp 用于简单命令,而不是这个。

$ rsync -ahSD --ignore-errors --force --delete --stats $SRC/ $DIR/
Run Code Online (Sandbox Code Playgroud)

cpio

这是一种更安全的方法,cpio。它和 tar 一样快,也许快一点。

$ cd $SRC && find . -mount -depth -print0 2>/dev/null | cpio -0admp $DEST &>/dev/null
Run Code Online (Sandbox Code Playgroud)

柏油

这也很好,并且在读取失败时继续。

$ tar --ignore-failed-read -C $SRC -cf - . | tar --ignore-failed-read -C $DEST -xf -
Run Code Online (Sandbox Code Playgroud)

请注意,这些仅适用于本地副本。

  • 为什么对 rsync 使用 -S 和 -D 标志? (2认同)

arj*_*nes 12

这个线程非常有用,因为有很多选项可以实现结果,我决定对其中的几个进行基准测试。我相信我的结果可以帮助其他人了解什么工作得更快。

要移动532Gb之间分布数据的1753200个文件,我们有那些时间:

  • rsync 耗时 232 分钟
  • tar 耗时 206 分钟
  • cpio 耗时 225 分钟
  • rsync + parallel 耗时 209 分钟

就我而言,我更喜欢使用rsync + parallel. 我希望这些信息可以帮助更多人在这些替代方案中做出决定。

完整的基准发布在这里

  • 谢谢@AmedeeVanGasse URL 在您报告后不久已修复:) (2认同)
  • 为什么不对 `cp` 进行基准测试?这是问题的标题! (2认同)

inn*_*naM 7

无论你喜欢什么。只是不要忘了-a,当你决定要使用开关cp

如果您真的需要答案:我会使用 rsync,因为它更灵活。复制完成前需要关机吗?只需 ctrl-c 并尽快恢复。需要排除一些文件?只需使用--exclude-from. 需要更改所有权或权限?rsync 会为你做到这一点。

  • cp -a 会更好。 (5认同)

小智 7

rsync命令始终计算其传输的每个字节的校验和。

命令行选项--checksum仅与文件校验和是否用于确定要传输的文件有关,即:

-c, --checksum 根据校验和跳过,而不是修改时间和大小”

手册页还说:

请注意,rsync 始终通过检查其整个文件校验和来验证每个传输的文件是否在接收端正确重建,但自动传输后验证与此选项的传输前“此文件是否需要要被更新?” 查看。

因此rsync,即使-c/ --checksum选项为“关闭” ,也始终在接收方计算整个文件的校验和。

  • 虽然您的帖子在这里添加了一些有趣的信息,但咆哮和侮辱会降低您帖子的价值。这个网站不是一个非建设性的咆哮论坛。如果您能够修改源代码,您是否已将修改作为补丁提交?你有没有在github上发布过你的版本?如果您对此感到如此强烈,那么您最好尝试做一些更具建设性的事情,而不是无谓的侮辱。 (15认同)

小智 6

rsync -aPhW --protocol=28使用 RSYNC 帮助加快这些大副本的速度。我总是使用 rsync,因为一想到要达到 90GiB 并且它会中断,我就害怕使用 CP

  • 在该命令字符串中使用旧协议的价值是什么? (2认同)

小智 5

rsync 很棒,但在处理非常大的目录树时存在问题,因为它将树存储在内存中。当我发现这个线程时,我只是想看看他们是否会解决这个问题。

我还发现:

http://matthew.mceachen.us/geek/gigasync/

您还可以手动分解树并运行多个 rsync。

  • 如果您使用版本 3,它不会将整个树保留在内存中,如果它很大,它会使用增量递归算法:http://www.samba.org/ftp/rsync/src/rsync-3.0.0-消息 (13认同)