AWS Athena 分区获取所有路径

nul*_*ull 11 amazon-web-services nosql presto amazon-athena aws-glue

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

旧版本的数据库和表只有 1 个分区级别,比如 id=x。我们拿一张桌子;例如,我们存储每个 id(产品)的支付参数,并且没有很多 ID。假设它在 1000-5000 左右。现在,在查询该表时,在 where 子句上传递 id 号,例如“.. where id = 10”。实际上,查询返回的速度非常快。假设我们每天更新数据两次。

最近,我们一直在考虑为一天添加另一个分区级别,例如“../id=x/dt=yyyy-mm-dd/..”。这意味着如果一个月过去了,分区数每天增长 xID 倍,如果我们有 3000 个 ID,我们每月大约会得到 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?
  • Athena 是否应该仅用于少量分区?

编辑

为了澄清上述声明,我从支持邮件中添加了一段。

来自支持

... 你提到你的新系统有 360000,这是一个很大的数字。因此,当您执行此操作时select * from <partitioned table>,Athena 首先下载所有分区元数据并搜索与这些分区映射的 S3 路径。这种为每个分区获取数据的过程会导致查询执行时间更长。...

更新

在 AWS 论坛上打开了一个问题。在 aws 论坛上提出的相关问题在这里

谢谢。

The*_*heo 6

如果不知道我们正在讨论的数据量、文件格式以及文件数量,就不可能正确回答这个问题。

\n\n

TL; DR 我怀疑您的分区包含数千个文件,并且瓶颈在于列出并读取所有文件。

\n\n

对于任何随时间增长的数据集,您应该根据查询模式对日期甚至时间进行时间分区。是否应该对其他属性进行分区取决于很多因素,最终结果往往是不分区更好。不总是,但经常。

\n\n

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

\n\n

当 Athena 执行查询时,它将首先从 Glue 加载分区。Glue 支持对分区进行有限过滤,并且将有助于修剪分区列表 \xe2\x80\x93\xc2\xa0so 据我所知,Athena 读取所有分区元数据是不正确的。

\n\n

当它具有分区时,它将LIST向分区位置发出操作以收集查询 \xe2\x80\x93\xc2\xa0 中涉及的文件,换句话说,Athena 不会列出每个分区位置,只会列出为查询选择的分区。这可能仍然是一个很大的数字,而这些列表操作绝对是一个瓶颈。如果分区中的文件超过 1000 个,情况会变得尤其糟糕,因为这是 S3 列表操作的页面大小,并且必须按顺序发出多个请求。

\n\n

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

\n\n

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

\n\n

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

\n\n

由于需要两分钟,我怀疑每个分区有数百个文件(如果不是数千个),并且您的瓶颈是在 S3 中运行所有列表和获取操作需要太多时间。

\n