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 路径,我的意思是这将是分区的一种神奇方式。也许它获取所有路径
编辑
为了澄清上述声明,我从支持邮件中添加了一段。
来自支持
... 你提到你的新系统有 360000,这是一个很大的数字。因此,当您执行此操作时
select * from <partitioned table>,Athena 首先下载所有分区元数据并搜索与这些分区映射的 S3 路径。这种为每个分区获取数据的过程会导致查询执行时间更长。...
更新
在 AWS 论坛上打开了一个问题。在 aws 论坛上提出的相关问题在这里。
谢谢。
如果不知道我们正在讨论的数据量、文件格式以及文件数量,就不可能正确回答这个问题。
\n\nTL; 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 列表操作的页面大小,并且必须按顺序发出多个请求。
列出所有文件后,Athena 将生成一个拆分列表,该列表可能等于也可能不等于文件列表 \xe2\x80\x93 某些文件格式是可拆分的,如果文件足够大,它们会被拆分并并行处理。
\n\n只有完成所有这些工作后,实际的查询处理才会开始。根据拆分总数和 Athena 集群中的可用容量,您的查询将被分配资源并开始执行。
\n\n如果您的数据采用 Parquet 格式,并且每个分区有一个或几个文件,则问题中的计数查询应在一秒或更短的时间内运行。Parquet 文件中有足够的元数据,计数查询不必读取数据,只需读取文件页脚。由于涉及多个步骤,很难让任何查询在不到一秒的时间内运行,但是命中单个分区的查询应该可以快速运行。
\n\n由于需要两分钟,我怀疑每个分区有数百个文件(如果不是数千个),并且您的瓶颈是在 S3 中运行所有列表和获取操作需要太多时间。
\n