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


59

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

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

Answers:


104

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

$ tar czf - <files> | ssh user@host "cd /wherever && tar xvzf -"

3
+1焦油管解决方案。如果带宽更大,CPU更少,则可以删除压缩标志(尽管gzip非常轻巧)。
Dietbuddha

2
您可以删除压缩标志,而改为在SSH(ssh -CCompression yes~/.ssh/config)中激活它。
sam hocevar 2011年

3
从来没有想过像这样使用tar。好吧,这就是为什么我来这里!
Shickadance先生,2011年

2
该命令可以稍微缩短一些:$ tar cz <files> | ssh user@host "cd /wherever; tar xvz"
carlito

2
@Greg破折号是POSIX兼容软件中的约定,根据上下文表示STDIN或STDOUT。第一个破折号表示“从/ dev / stdin读取”,第二个破折号(实际上在远程主机上执行)表示“ / dev / stdin”。管道和ssh连接这两个过程。请参阅unix.stackexchange.com/questions/16357/…了解更多信息。
理查德·梅茨勒

22

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

$ tar -C /path/to/src/dir -jcf - ./ | ssh user@server 'tar -C /path/to/dest/dir -jxf -'

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

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

$ rsync -az -e ssh /path/to/src/dir/ user@server:/path/to/dest/dir/

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


16

use rsync,它使用SSH。

用法:

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

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

您可以使用scp -C启用压缩,但可以使用rsync


不幸的是,rsync在源计算机上不可用,也没有sshd。
nmichaels 2011年

1
客户端计算机上的那些操作不需要sshd。
polemon 2011年

3

您可以tar使用ssh在两端运行。 scpssh善良家庭的一部分,所以您可能两端都有。

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

也可能有一种方法可以将gzip或bzip2处理到管道中以减少网络流量。


3

@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 user@host "cd /wherever && pv -qCB 512M | zstd -cd -T0 --long=31 | tar xf -"

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

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

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

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


2

如果两端都有gzip: sourcehost$ cd sourcedir && tar cf - . | gzip -c - | ssh user@destinationhost "cd destinationdir && gzip -c -d | tar xf -"

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

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


2

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

因此在本地计算机上:

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

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

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

高温超导


1

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

sshfs user@remotehost:/path/on/remote /path/on/local

1

虽然不是最优雅,但是特别是因为它不会复制单个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_name yourname@yourservername:destination_folder_name

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


好吧,这显然比输入一千个scp命令花费的时间更少。但是问题是关于“网络开销”的。您的解决方案使用网络是否比单独复制每个文件少?您的解决方案是否比已发布的七个解决方案都优越?
G人

Snap,我不好-我完全错过了网络开销部分-感谢您指出@ G-Man。我更新了答案,我仍然觉得如果有人像我一样偶然发现类似问题以及当我偶然发现这个问题时,它可能还是有用的。
JGlass
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.