存储许多小文件(在 S3 上)?

Posted

技术标签:

【中文标题】存储许多小文件(在 S3 上)?【英文标题】:Storing many small files (on S3)? 【发布时间】:2019-09-27 07:25:18 【问题描述】:

我每天要添加 200 万个压缩 html 文件 (100-150KB),我需要长期存储这些文件。 热数据(70-1.5 亿)被半定期访问,任何比这更早的数据几乎从未被访问过。

这意味着我每天要额外存储 200-300GB 的文件。

现在,标准存储成本为每 GB 0.023 美元,Glacier 为 0.004 美元。

虽然 Glacier 很便宜,但问题是它有额外的成本,所以将 200 万个文件转储到 Glacier 中是个坏主意:

PUT requests to Glacier $0.05 per 1,000 requests

Lifecycle Transition Requests into Glacier $0.05 per 1,000 requests

有没有办法将文件粘合在一起,但可以单独访问它们?

【问题讨论】:

存储为单个 ZIP 文件以节省存储空间。访问时,解压缩 ZIP 并提供一个文件 @Justinas 这意味着这些文件将无法单独访问。 它将通过代理服务 无论你最终做什么,如果你创建一个大的存档文件,你最终需要把整个文件从冰川中取出,然后你可以使用字节范围请求来拉下它的一部分。此外,从冰川中检索文件需要时间,在某些情况下需要几个小时。就个人而言,我会研究标准 IA,并创建一个定制的存档格式,该格式在开头有一个带有内容的标头,因此您可以使用字节范围请求来读取标头,然后在知道数据的位置后获取数据。也许将检索的复杂性包装在 Lambda 中,这样客户就不需要知道发生了什么。 如您所写,Glacier 的价格为 0.004 美元。但是您不能使用成本低 4 倍(0.00099 美元)的深度存档? 【参考方案1】:

重要的一点是,如果您需要提供对这些文件的快速访问权限,Glacier 可以让您在最多 12 小时内访问这些文件。所以最好的办法是使用S3 Standard – Infrequent Access(每GB 0,0125 美元,毫秒访问)而不是S3 Standard。也许对于一些真正不使用数据的人Glacier。但这仍然取决于您需要这些数据的速度。

我建议如下:

由于 html(文本)文件具有良好的压缩水平,您可以将历史数据压缩为大 zip 文件(每天、每周或每月),因为它们一起可以得到更好的压缩;李> 制作一些索引文件或数据库以了解每个 html 文件的存储位置; 仅从档案中读取所需的 html 文件无需解压整个 zip 文件。请参阅 example in python 如何实现。

【讨论】:

【参考方案2】:

Glacier 在文件数量方面对成本极为敏感。最好的方法是创建一个 Lambda 函数来为您处理压缩、解压缩操作。

考虑这种方法:

Lambda 每小时从当天的 200 万个文件中创建 archive_date_hour.zip,这通过创建 24 个巨大的档案文件解决了“每个对象”的成本问题。 在s3 存储桶上设置policy 以将过期对象移至1 天前的冰川。 使用解压缩 Lambda 函数从 zip 文件中的 glacier 存储桶中提取和提取潜在的热门项目。 保留主要的s3 存储桶用于频繁访问的热文件,作为压缩/解压缩操作的工作目录,以及每天收集新文件

【讨论】:

【参考方案3】:

您的文件太小了。您可能需要将它们组合在 ETL 管道中,例如胶水。您还可以使用Range 标头(即-range bytes=1000-2000)下载S3 上的部分对象。

如果您这样做,您将需要找出跟踪字节范围的最佳方法,例如在合并记录每个字节范围的文件之后,并将客户端更改为也使用 range

但正确的方法取决于如何访问这些数据并找出模式。如果有人查看TinyFileA 也查看TinyFileB,您可以将它们组合在一起,然后将它们与他们可能使用的其他文件一起发送。我会找出对消费者有意义的文件的逻辑分组,并将减少他们需要的请求数量,而不会发送太多不相关的数据。

【讨论】:

以上是关于存储许多小文件(在 S3 上)?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 EMR 生成的 S3 上的小文件与数千个 reducer 合并

python 将小文件写入s3存储桶的lambda处理函数

从S3存储桶下载百万个文件

针对大量小文件优化 S3 下载

Spark - 加载许多小 csv 需要很长时间

如何使用许多小文件加速 Spark 的 parquet 阅读器