用于高效 Athena 查询的 S3 分区(文件大小)

Posted

技术标签:

【中文标题】用于高效 Athena 查询的 S3 分区(文件大小)【英文标题】:S3 partition (file size) for effecient Athena query 【发布时间】:2019-06-10 02:51:11 【问题描述】:

我有一个将每日记录加载到 S3 的管道。然后,我利用 AWS Glue Crawler 创建分区以促进 AWS Athena 查询。但是,如果与其他数据相比,则存在大量分区数据。

S3 文件夹/文件显示如下:

s3.ObjectSummary(bucket_name='bucket', key='database/table/2019/00/00/2019-00-00.parquet.gzip')   7.8 MB

s3.ObjectSummary(bucket_name='bucket', key='database/table/2019/01/11/2019-01-11.parquet.gzip')  29.8 KB
s3.ObjectSummary(bucket_name='bucket', key='database/table/2019/01/12/2019-01-12.parquet.gzip')  28.5 KB
s3.ObjectSummary(bucket_name='bucket', key='database/table/2019/01/13/2019-01-13.parquet.gzip')  29.0 KB
s3.ObjectSummary(bucket_name='bucket', key='database/table/2019/01/14/2019-01-14.parquet.gzip')  43.3 KB
s3.ObjectSummary(bucket_name='bucket', key='database/table/2019/01/15/2019-01-15.parquet.gzip') 139.9 KB

在每行末尾显示文件大小。请注意,2019-00-00.parquet.gzip 包含 2019-01-11 之前的所有记录,因此它的大小很大。我读过this,它说“如果您的数据严重偏向于一个分区值,并且大多数查询都使用该值,那么开销可能会抵消最初的好处。”

所以,我想知道我是否应该将2019-00-00.parquet.gzip 拆分为具有不同分区的较小拼花文件。例如,

key='database/table/2019/00/00/2019-00-01.parquet.gzip',
key='database/table/2019/00/00/2019-00-02.parquet.gzip',
key='database/table/2019/00/00/2019-00-03.parquet.gzip', ......

但是,我认为这种分区并不是很有用,因为它不能反映旧记录的存储时间。我愿意接受所有解决方法。谢谢。

【问题讨论】:

如果您显示的文件大小是真实的,那么您不应该关心性能低下。顺便说一句,这真的很容易测试,但我怀疑你会注意到文件大小的一些差异。 @Roberto 很抱歉这么晚才回复您。是的,文件大小是真实的。您是否介意分享测试方法,即使可能很难注意到差异?我对此真的很陌生。另外,根据您的经验,您认为这是存储parquet.gzip 文件的好方法吗? 嗨,只需复制你最大的 parquet 文件(139.9KB 的那个)并将它们保存在同一个分区中,以使分区之间的差异更大,并测试几个查询,检查时间,删除复制并再次测试。现在,就 parquet 文件的分区方式而言,这在很大程度上取决于您的用例。没有最好的方法,只有适合每种情况的正确方法。在压缩方面,parquet 默认情况下已经在内部进行了 GZIP 压缩,但如果 Glue 为您完成这项工作,那么我不会抱怨 :) 【参考方案1】:

如果您的数据的完整大小总共小于几 GB,则您根本不需要对表进行分区。对小型数据集进行分区对性能的影响远大于对性能的帮助。将所有文件保存在同一个目录中,未分区表中的深层目录结构也会影响性能。

对于小型数据集,只要文件不多(尽量保持在 100 以下),最好不要分区。如果您出于某种原因必须拥有大量小文件,您可能会从分区中受益,但在这种情况下进行基准测试。

当数据的大小很小时,例如在您的情况下,在 S3 上查找文件、打开和读取它们的开销将高于实际处理它们。

如果您的数据增长到数百兆字节,您可以开始考虑分区,并以分区大小约为 100 兆字节到 1 GB 的分区方案为目标。如果您的数据存在时间组件(在您的情况下似乎存在),那么时间是最好的分区依据。首先查看使用年份作为分区键,然后是月份,依此类推。当然,具体如何对数据进行分区取决于查询模式。

【讨论】:

以上是关于用于高效 Athena 查询的 S3 分区(文件大小)的主要内容,如果未能解决你的问题,请参考以下文章

我可以从存储在 S3 中的 sql 文件运行 Athena 查询吗

AWS Athena 可以更新或插入存储在 S3 中的数据吗?

在不同账户的 Lambda 中从 AWS Athena 查询 S3 文件时访问被拒绝

Amazon athena 无法读取 S3 Access 日志文件,Athena 选择查询为每一列返回空结果集

Redshift Spectrum 性能对比 Athena

重命名 Athena 中的分区列名称