AWS Athena分区获取所有路径

时间:2019-12-26 12:18:32

标签: amazon-web-services nosql aws-glue presto amazon-athena

最近,当分区数量很多时,我遇到了AWS Athena的问题。

旧版本的数据库和表只有1个分区级别,例如id = x。我们来一张桌子。例如,我们在每个ID(产品)存储付款参数的地方,没有足够的ID。假设其在1000-5000附近。现在,在查询带有where子句的id号的表时,例如“ .. where id = 10”。实际上,查询返回的速度非常快。假设我们每天两次更新数据。

最近,我们一直在考虑为一天添加另一个分区级别,例如“ ../id=x/dt=yyyy-mm-dd/ ..”。这意味着如果一个月过去了,并且每天有3000个ID,则分区号每天会增加xID倍,我们每个月大约可获得3000x30 = 90000个分区。因此,分区数量迅速增长。

假设有3个月大的数据(约27万个分区),我们希望看到类似以下查询的查询最多在20秒左右的时间内返回。

select count(*) from db.table where id = x and dt = 'yyyy-mm-dd'

这大约需要一分钟。

真实案例

事实证明,Athena首先获取所有分区(元数据)和s3路径(无论where子句的用法),然后过滤您希望在where条件下看到的s3路径。第一部分(按分区提取所有s3路径的时间与分区数成正比)

您拥有的分区越多,查询执行的速度就越慢。

直觉上,我希望Athena仅获取where子句中陈述的s3路径,这意味着这将是分区魔术师的一种方法。也许获取所有路径

  • 有人知道解决方法吗,还是我们以错误的方式使用了Athena?
  • 雅典娜应该只用于少数分区吗?

修改

为了澄清上述说法,我在支持邮件中添加了一部分。

来自支持部门

  

...   您提到您的新系统有360000个庞大的数字。   因此,当您进行select * from <partitioned table>时,Athena首先下载所有分区元数据并搜索与   这些分区。此过程为每个分区获取数据   导致查询执行时间更长。   ...

更新

在AWS论坛上打开了一个问题。在aws论坛上引发的链接问题是here

谢谢。

1 个答案:

答案 0 :(得分:2)

如果不知道数据量,什么文件格式以及我们在谈论多少文件,就不可能正确回答。

TL;灾难恢复我怀疑您的分区包含成千上万个文件,并且瓶颈正在列出并全部读取。

对于随时间增长的任何数据集,您都应该根据查询模式对日期甚至时间进行时间分区。如果您应该在其他属性上进行分区取决于很多因素,最后通常会发现,最好不要分区。不是总是,但是经常。

在许多情况下,使用合理大小(〜100 MB)的镶木地板比分区更有效。原因是分区增加了必须在S3上列出的前缀数量以及必须读取的文件数量。在许多情况下,单个100 MB的Parquet文件可能比十个10 MB的文件效率更高。

Athena执行查询时,它将首先从Glue加载分区。 Glue supports limited filtering on partitions,并且会在修剪分区列表方面有所帮助–据我所知,雅典娜读取所有分区元数据并不是真的。

具有分区时,它将对分区位置执行LIST操作,以收集查询中涉及的文件–换句话说,Athena不会列出每个分区位置,仅是为查询选择的分区中的位置。这可能仍然很大,这些列表操作绝对是瓶颈。如果一个分区中有1000个以上的文件,这将变得特别糟糕,因为这是S3列表操作的页面大小,并且必须按顺序进行多个请求。

列出所有文件后,Athena会生成一个拆分列表,该拆分列表可能等于也可能不等于文件列表–一些文件格式是可拆分的,如果文件足够大,则将它们拆分并并行处理。

仅在完成所有这些工作之后,才开始实际的查询处理。根据拆分的总数和Athena群集中可用容量的数量,将为查询分配资源并开始执行。

如果您的数据是Parquet格式,并且每个分区有一个或几个文件,则问题中的count查询应该在一秒钟或更短的时间内运行。 Parquet的文件中有足够的元数据,因此计数查询不必读取数据,而只需读取文件页脚即可。由于涉及多个步骤,因此很难在不到一秒钟的时间内运行任何查询,但是命中单个分区的查询应该可以快速运行。

由于花了两分钟,我怀疑每个分区中有数百个文件(如果不是数千个),而您的瓶颈在于,在S3中运行所有列表并进行操作会花费太多时间。