it-swarm.cn

如何最好地通过scp复制大量小文件?

我的目录有几个千兆字节和数千个小文件。我想多次使用scp通过网络复制它。源计算机和目标计算机上的CPU时间便宜,但是通过单独复制每个文件而增加的网络开销非常大。我会对其进行tar/gzip压缩,然后将其运送过来,但是源计算机的磁盘空间不足。

有没有办法将tar -czf <output> <directory>的输出传递给scp?如果没有,还有其他简单的解决方案吗?我的源计算机是古老的(SunOS),所以我不想在上面安装东西。

63
nmichaels

您可以在ssh会话中通过管道传递tar:

$ tar czf - <files> | ssh [email protected] "cd /wherever && tar xvzf -"
110
pdo

带有bzip2压缩的Tar应该从网络和cpu上承担尽可能多的负载。

$ tar -C /path/to/src/dir -jcf - ./ | ssh [email protected] 'tar -C /path/to/dest/dir -jxf -'

不使用-v,因为屏幕输出可能会减慢该过程。但是,如果您想要详细的输出,请在tar(-jcvf),而不是在远程部分。

如果您在同一目标路径上重复复制(例如更新备份副本),则最好的选择是使用压缩进行rsync。

$ rsync -az -e ssh /path/to/src/dir/ [email protected]:/path/to/dest/dir/

请注意,src和dest路径均以/结尾。同样,不使用-v-P标志是故意的,如果需要详细输出,请添加它们。

23
forcefsck

使用 rsync ,它使用SSH。

用法:

rsync -aPz /source/path destination.server:remote/path

Rsync开关关心压缩和I节点信息。 -P显示每个文件的进度。

您可以使用 scp -C,启用压缩,但如果可能,请使用rsync

16
polemon

您可以使用ssh在两端运行tarscpssh善良家族的一部分,因此您可能两端都有。

 8:03AM 12 % tar cf - some_directory | ssh dest_Host "tar xf -"

也可以使用一种方法将gzip或bzip2放入管道中,以减少网络流量。

3
Bruce Ediger

@pdo的答案很好,但是可以通过缓冲区和良好的压缩来提高速度,并添加进度条。

网络经常是瓶颈,速度会随着时间而变化。因此,它有助于在通过网络发送数据之前缓冲数据。这可以通过pv完成。

此外,通常可以使用适当的压缩算法来提高速度。 Gzip(与上面使用的类似)是一种快速压缩算法,但是一般而言,zstandard(zstd)(对于高压缩比,LZMA/LZMA2(xz)将更好地压缩,同时更快。 xz和zstd已经内置了多核支持。要在多核中使用gzip,可以使用Pigz。

这是一个通过网络发送进度条,缓冲和zstandard压缩的数据的示例:

tar cf - . | pv -perabs $(du -sk . | cut -f 1)K | zstd -14 --long=31 -T0 | pv -qCB 512M | ssh [email protected] "cd /wherever && pv -qCB 512M | zstd -cd -T0 --long=31 | tar xf -"

第一个pv将显示进度(p),估计时间(e),传输速率(r),平均速率(a),传输的总字节数(b)。总大小用du估算,并添加到大小选项(s)。进度是在压缩和缓冲之前测量的,因此虽然不是很准确,但是仍然很有帮助。

zstd与压缩设置14一起使用。可以根据网络和CPU速度来减少或增加该数目,因此zstd比网络速度快一点。在Haswell 3.2 GHz CPU上具有四个内核时14的速度约为120 MB/s。在示例中,使用了长模式31(使用2 GB的窗口,需要大量RAM,但是非常好,例如用于压缩数据库转储) 。 T0选项将线程数量设置为核心数量。应该意识到,与长模式一起使用时,这些设置会占用大量内存。

Zstd的问题在于,大多数操作系统都不提供版本大于等于1.3.4的版本。此版本对于适当的多核和长期支持是必需的。如果不可用,则可以仅使用make -j4 && Sudo make installhttps://github.com/facebook/zstd 进行编译和安装。除了zstd,还可以使用xz或pigz。 xz速度很慢,但压缩效果很好(在慢速连接上效果很好),pigg/gzip速度很快,但压缩效果却不太好。然后再次使用pv,但用于缓冲(q表示安静,C表示无拼接模式(始终需要缓冲),而B设置缓冲区大小) 。

在该示例中,在接收器端也使用了缓冲区。这通常是不必要的(因为解压缩和硬盘写入速度大多数时候都高于网络速度),但通常也不会造成损害。

3
Fabian Heller

如果两端都有gzip:sourcehost$ cd sourcedir && tar cf - . | gzip -c - | ssh [email protected] "cd destinationdir && gzip -c -d | tar xf -"

如果源计算机上没有gzip,请确保已在目标计算机上解压缩:sourcehost$ cd sourcedir && tar cf - . | compress | ssh [email protected] "cd destdir && uncompress | tar xf -"

这比先将其压缩,然后发送,然后解压缩要快得多,并且两边都不需要额外的磁盘空间。我在tar上略过了压缩(z)标志,因为您可能在古老的一面没有它。

2
MattBianco

或者,您也可以根据需要采用其他方法。那就是通过网络拉压缩包,而不是像建议的那样将其压缩。这不能解决问题的重复部分,而rsync最适合此问题,但可能有tar开关可以提供帮助。

因此在本地计算机上:

ssh remote 'tar zcf - /etc/resolv.conf' | tar zxf -

最好先放在正确的目录中,否则必须在末尾的untaring命令上使用-C开关。

仅在需要时提及此。就我而言,因为我的本地服务器处于落后状态,因此需要花费一些网络努力才能实现以前提到的方式。

高温超导

2
DaveQB

或者通过sshfs挂载远程文件系统

sshfs [email protected]:/path/on/remote /path/on/local
1
ivanivan

虽然不是最优雅,但特别是因为它不会复制单个Zip或tar文件并且会加倍复制,以免降低网络负担,所以我唯一的选择是使用scp -r

-r

      递归复制整个目录。请注意scp跟随在树遍历中遇到的符号链接。
来源: scp(1)

我遇到了一个30 GB压缩tar文件的磁盘空间不足的问题。我以为gunzip可以内联处理,也就是删除正解压缩的原始文件(我可能错过了Google的搜索结果),但找不到任何东西。

最后,由于我厌倦了尝试多次等待新的TAR或Zip文件完成tar'ing或zipping的工作,所以我终于做到了:

  1. 从原始服务器/ PC /笔记本电脑,导航到包含大量文件/文件夹的文件夹所在的目录。
  2. scp -r source_folder_nameyourname@yourservername:destination_folder_name

然后,喝点啤酒,咖啡或爆米花,然后等待。好消息是,如果网络连接“停滞”,scp将重试。只是希望它不会完全消失。

1
JGlass