有没有更快的 cp 替代品来复制大文件(~20 GB)?

And*_*rew 45 cp file-copy

我是研究生,我所在的小组维护一个 Linux 集群。集群的每个节点都有自己的本地磁盘,但是这些本地磁盘比较小,没有配备自动备份。因此,该组拥有一个具有许多 TB 存储空间的文件服务器。我是一个相对的 Linux 新手,所以我不确定文件服务器在速度、网络能力等方面的规格是什么。我从经验中知道本地磁盘在 I/O 方面比文件服务器快得多. 大约有十几个人使用文件服务器。

使用cp将大约 20 GB 的文件从文件服务器复制到其中一个本地磁盘平均需要大约 11.5 分钟的实时时间(根据time)。我知道这个cp操作效率不高,因为(1)time告诉我这样一个副本的系统时间只有~45秒;并且因为 (2) 当我top在复制过程中检查时,%CPU非常低(通过检查,平均约为0-10%)。

使用cp将相同的 ~20 GB 文件从本地磁盘上的一个文件夹复制到同一本地磁盘上的另一个文件夹需要更少的时间 - 实时大约 9 分钟(系统时间约为 51 秒,根据time)。因此,显然文件服务器比本地磁盘慢一些,正如预期的那样,但可能不会明显变慢。我很惊讶从本地复制到同一本地的速度不超过 9 分钟。

我需要将 ~200 个大文件(每个 ~20 GB)从文件服务器复制到本地磁盘之一。所以,我的问题是:在 Linux 中复制大文件有没有更快的替代方法cp (或者cp我可以使用任何标志来加速复制?)即使我可以以某种方式将这个复制时间缩短一分钟,这也会有很大帮助。

我确信购买新的、速度更快的硬件磁盘,但我无法访问此类资源。我也不是系统管理员——我只是一个(新手)用户——所以我无法访问有关磁盘负载的更详细信息。我知道虽然每天大约有十几个人使用文件服务器,但我是唯一使用这个特定节点/本地磁盘的人。

der*_*ert 53

复制期间%CPU应该很低。CPU 告诉磁盘控制器“从扇区 X-Y 中将数据抓取到 Z 处的内存缓冲区中”。然后它会去做别的事情(或者睡觉,如果没有别的事情的话)。当数据在内存中时,硬件会触发中断。然后 CPU 必须复制几次,并告诉网卡“在内存位置 A、B 和 C 传输数据包”。然后它又回到做其他事情。

你正在推动~240mbps。在千兆 LAN 上,您应该能够达到至少 800mbps,但是:

  1. 这在使用文件服务器的每个人之间共享(可能还有交换机之间的连接等)
  2. 这受到文件服务器处理写入速度的限制,记住它的磁盘 I/O 带宽由使用它的每个人共享。
  3. 您没有指定访问文件服务器的方式(NFS、CIFS (Samba)、AFS 等)。您可能需要调整您的网络安装,但在最近的任何事情上,默认值通常都非常合理。

对于跟踪瓶颈,iostat -kx 10这将是一个有用的命令。它会向您显示本地硬盘的利用率。如果你可以在文件服务器上运行它,它会告诉你文件服务器有多忙。

一般的解决方案是加速瓶颈,当然你没有预算。但是,在一些特殊情况下,您可以找到更快的方法:

  • 如果文件是可压缩的,并且您有一个快速的 CPU,那么即时进行最小压缩可能会更快。像lzop或也许gzip --fastest
  • 如果您只在这里和那里更改一些位,然后将文件发回,则仅发送增量会快得多。不幸的是,rsync在这里并没有真正的帮助,因为它需要读取双方的文件才能找到增量。相反,您需要在更改文件时跟踪增量……这里的大多数方法都是特定于应用程序的。但是您可能可以使用设备映射器(请参阅全新的dm-era 目标)或 btrfs 来安装某些东西。
  • 如果您将相同的数据复制到台机器上,您可以使用类似 udpcast 的东西一次将其发送到所有机器。

而且,既然你注意到你不是系统管理员,我猜这意味着你有一个系统管理员。或者至少有人负责文件服务器和网络。您可能应该问他/她/他们,他们应该更熟悉您的设置细节。您的系统管理员至少应该能够告诉您可以合理预期的传输速率。


小智 18

这可能是一个更快的替代方案,并且您不会在两天内阻塞网络:使用一两个大 USB(如果有 USB 3)或 FireWire 磁盘,将其连接到服务器并将文件复制到磁盘。将磁盘传送到本地计算机。将文件复制到机器上。

  • Sneakernet (http://en.wikipedia.org/wiki/Sneakernet) 可以非常快:永远不要低估一辆装满磁带的旅行车在高速公路上疾驰的带宽。 (27认同)

Bre*_*ong 10

如果您有直接的 SSH(或 SFTP)访问(询问您的系统管理员),您可以使用scp压缩 ( -C):

scp -C you@server:/path/to/yourfile .
Run Code Online (Sandbox Code Playgroud)

当然,这只有在文件可压缩时才有用,这将使用更多的 CPU 时间,因为它将使用加密(因为它通过 SSH)和压缩。

  • @lgeorget 考虑到硬盘驱动器有多慢,我怀疑加密的开销不会很大。我考虑过添加一些关于 `-c none` 的内容,但这 [似乎是非标准的](http://www.mail-archive.com/slug@slug.org.au/msg62497.html)。 (3认同)

psu*_*usi 9

你对高效的定义是倒退的。更有效的实现会浪费更少的CPU 时间。在本地副本上,您的平均吞吐量(读取 + 写入)约为 74 MB/s,这与单个硬盘的吞吐量差不多。


Mic*_*jer 8

cp执行是最有可能不会成为瓶颈。尝试通过iotop在服务器和集群节点上观察 IO 使用情况。这会给你一个想法,你可以提高性能。

另一个技巧是避免从同一主机复制相同的数据。例如,如果您有相同的 20G 文件要通过网络从文件服务器分发到所有集群节点,那么如果您以对等方式复制文件而不是从一台服务器到所有客户端复制文件,它会工作得更快。实现起来有点复杂,但您甚至可以尝试使用一些命令行 p2p,例如直连集线器。

如果在那个 20G 文件中,有些部分是通用的,有些是特定于集群节点的,则考虑将其拆分为通用和特定部分,然后以 p2p 方式分发公共部分。


wol*_*ajr 8

这些文件的性质/内容可能会有所不同。我知道您需要将 200 个文件,每个约 20 GB,从一台计算机复制到另一台计算机,是吗?

如果这些文件是可压缩的或具有相似/相同的部分,则有两种方法:

  • 在复制之前压缩它们,或者在启用 zip 的计算机之间创建一个隧道。所以,如果网络是瓶颈,它会快一点

  • 如果文件非常相似,或者它们之间共享一些共同的内容,请尝试使用rsync。它将花费一些时间来查找文件中的共同点,并且不需要逐字复制它,因为它会根据共同点重建它。

编辑

你需要多次复制这些文件吗??(例如复制 -> 使用这些文件 -> 更改计算机 A 中文件中的某些内容 -> 再次将文件复制到计算机 B)

如果是这样,rsync 会有所帮助,因为它会尝试检测版本之间的相同内容,而不复制未更改的内容。

第三种方法:如果上述方法正确(更改文件,然后将所有文件再次复制到第二台计算机),您可以尝试binary diff在第二台计算机中更改第一台计算机中更改的内容。


mdp*_*dpc 6

我在这里看到以下内容,加密不是一个好主意,因为它可能会增加要传输的数据量。

如果您在两个系统之间进行复制,那么瓶颈当然是服务器之间的连接。

如果您在本地复制,请查看进程如何进行,它是单线程的,因此标准 Linux 实用程序使用:

- for all blocks in a file
      read a block
      write a block
Run Code Online (Sandbox Code Playgroud)

此操作没有并发性。

为了加快速度,你可以使用这样的东西:

  buffer -i infile -o outfile -m size-of-shared-memory-default-1MByte
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅 buffer(1) 手册页。

buffer 命令设置两个进程来并发运行复制进程:一个用于读取,另一个用于写入,它使用共享内存缓冲区在两个进程之间进行数据通信。共享内存缓冲区是经典的循环缓冲区,可防止覆盖未写入的数据和写入已写入的数据。我已经使用这个程序在从磁盘到磁带的传输中减少了大约 10-20% 的复制时间。