将数百万个小文件合并在一起的最快方法

Hao*_*ang 10 tar zip archive file-transfer

我经常需要在服务器之间或向 aws s3 传输数百万个小文件(小图像、txt、json),平均每个文件 5-50k。

除了 zip/tar -cf 之外,是否有更快的方法将它们合并到单个文件中以优化传输速度?

Bib*_*Bib 13

类似的东西tar cz * | ssh <host> "tar xfc -"?说真的,有什么问题吗tar?此命令不会创建任何中间文件。

  • 或者更好的 `tar --zstd c * | ssh &lt;host&gt; "tar xf -"`,因为 zstd 主要废弃了 gzip,在类似或更好的压缩比下速度更快。 (3认同)

Rom*_*nov 9

从其他答案中发展想法,您可以通过管道发送信息,甚至不在本地创建文件tar。命令将类似于:

tar cf - * | aws s3 cp - s3://some-bucket/archive.tar
Run Code Online (Sandbox Code Playgroud)

该命令的优点是可以并行运行tar和命令。aws您甚至可以添加压缩(这将再次并行执行)

tar cf - * | gzip -c | aws s3 cp - s3://some-bucket/archive.tar.gz
Run Code Online (Sandbox Code Playgroud)

为了简化操作,您可以使用文件的顶级目录而不是使用*

tar cf - top_level_directory | aws s3 cp - s3://some-bucket/archive.tar
tar cf - top_level_directory | gzip -c | aws s3 cp - s3://some-bucket/archive.tar.gz
Run Code Online (Sandbox Code Playgroud)

受到其他答案的启发,您可以使用cpio。似乎更快并且生成更小的文件:

ls |cpio -o |gzip -c | aws s3 cp - s3://some-bucket/archive.cpio.gz
Run Code Online (Sandbox Code Playgroud)

  • 天哪...运行它然后暂停它并查找设置了哪些文件描述符。它们都是管道式的。时间上的任何差异纯粹是任意的。 (4认同)
  • 我认为这不准确。我刚刚运行了 `time tar czf file.tgz file` 和 `time tar cf - file | time tar czf file.tgz file` gzip -c &gt; file.tgz` 在 SSD 上使用 288M 文件,第一个花费了 0m20.004s(真实),而第二个花费了 0m20.141s。因此,至少在这个特定的测试中,使用管道的速度稍微慢一些。当然,差异很小,但可能与较大的文件相关。或许?至少,管道似乎没有增加任何优势来证明命令复杂性的增加是合理的。 (3认同)
  • 运行 `tar|gzip` 与 `tar c` 相同,它们都以管道并行方式运行。否认这一点意味着要么将数据保存在缓冲区中 - 导致内存耗尽,要么创建一个临时文件,这两者都不是真的。 (3认同)
  • 我认为你不需要 `-c`、`tar -cf - * | 压缩包 | ...` 应该有效。至少在我的 Linux 机器上有这些工具。另外,您根本不需要“gzip”,您可以执行“tar -czf - *”,除非添加对“gzip”的单独调用有一些优势。 (2认同)
  • 呵呵,听起来这个问题值得问一下!我怀疑是否使用 SSD 或 HDD 对此也非常相关。 (2认同)

Aus*_*arn 7

是的,有很多选择。

\n

一是永远不要创建中间文件,正如其他答案中所建议的那样。这会减少本地 IO,但无法恢复部分上传。

\n

还有其他选项可以进一步改进:

\n
    \n
  • 对存档使用压缩。GZip 是经典的,但它\xe2\x80\x99s 有点慢。LZ4 如今已相当广泛使用,速度极快,并且仍然可以为您提供不错的压缩比tar以及您\xe2\x80\x99 所描述的内容。ZSTD 的速度不如 LZ4,但会在更短的时间内获得与 GZip 类似的压缩率。无论选择如何,这都可能会显着减少要传输的总数据量。
  • \n
  • 考虑使用cpio而不是tar. tar不完全是一种节省空间的存档格式。这通常并不重要,但如果您要处理数百万个非常小的文件,则开销实际上相当大。cpio仍然有不小的开销,但它比 xe2x80x99 少tar,因此理论上在cpio这里使用应该会导致要传输的数据量显着减少。
  • \n
  • 考虑创建多个档案,每个档案包含文件的子集(例如,每个档案中可能不超过 100k 个文件),然后并行上传这些档案。假设源系统具有快速的互联网连接和相对较快的存储,这(几乎肯定)会比上传一个大档案更快,因为它可以更好地并行化本地 IO(并且因为 AWS 也可以在其端并行处理事物)。\xe2\x80\x98此处的最佳\xe2\x80\x99 大小通常足够小,因此您不需要使用分段上传。即使您跳过在本地创建中间文件,这也有助于恢复部分上传,因为您只需上传尚未上传的\xe2\x80\x99t 档案。
  • \n
\n