【问题标题】:AWS Athena partition fetch all pathsAWS Athena 分区获取所有路径
【发布时间】:2020-04-16 16:39:01
【问题描述】:

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

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

最近,我们一直在考虑为一天添加另一个分区级别,例如“../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 论坛上提出的链接问题是 here

谢谢。

【问题讨论】:

  • 您是否已经考虑过分桶?
  • @PiotrFindeisen 你的意思是分桶天而不是分区天?我没有尝试过,但它会加速where子句吗?如果您打算获得最佳文件数,您可以假设我们在每个分区中都有最佳文件数
  • 我不知道你的查询模式(这是关键部分,真的)。直觉上,我会先尝试按dt 进行分区,然后按id 进行分桶。但是,我不知道您为什么按id 进行分区以及id 实际上是什么。此外,没有最佳文件数之类的东西。如果您使用 ORC 或 Parquet,您只需关心文件至少为 32-64MB,但单个文件可能会很大。
  • 顺便说一句,正如您所见,这不是一个非常适合的简单问题,并且没有单一的答案。我建议您通过Presto community slack 咨询 Presto 专家。
  • @null :这可能对您的用例很有帮助:aws.amazon.com/premiumsupport/knowledge-center/…

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


【解决方案1】:

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

TL; DR 我怀疑您有包含数千个文件的分区,并且瓶颈是列出并全部读取它们。

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

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

当 Athena 执行查询时,它将首先从 Glue 加载分区。 Glue supports limited filtering on partitions,并且将有助于修剪分区列表 - 所以据我所知,Athena 读取 所有 分区元数据是不正确的。

当它拥有分区时,它将向分区位置发出LIST 操作以收集查询中涉及的文件——换句话说,Athena 不会列出每个分区位置,只是为查询选择的分区中的那些。这可能仍然是一个很大的数字,这些列表操作肯定是一个瓶颈。如果一个分区中有超过 1000 个文件会变得特别糟糕,因为这是 S3 列表操作的页面大小,并且必须按顺序发出多个请求。

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

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

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

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

【讨论】:

  • 感谢您的详细回答。实际上,正如您所说,我们已经寻求最佳文件大小(存储镶木地板),但瓶颈是 s3 列表,这可能是由于 s3 列表的分页为 1000 页。我们的问题是在粘合上应用两个分区列,这不是最佳实践,因此我们将表结构更改为每个表应用 1 个分区列,它几乎解决了这个问题。
猜你喜欢
  • 2019-09-16
  • 1970-01-01
  • 1970-01-01
  • 2014-10-16
  • 1970-01-01
  • 2017-12-19
  • 2019-05-03
  • 2017-01-02
  • 1970-01-01
相关资源
最近更新 更多