AWS Athena 对于 api 来说太慢了?

ath*_*mas 13 amazon-web-services amazon-athena

计划是从 aws 数据交换中获取数据,将其移动到 s3 存储桶,然后通过 aws athena 查询数据 api。一切正常,只是感觉有点慢。

无论是数据集还是查询,我都无法在 athena 响应时间中低于 2 秒。这对于一个 API 来说非常重要。我检查了最佳实践,但似乎这些也超过了 2 秒。

所以我的问题是:2 秒是雅典娜的最短响应时间吗?

如果是这样,那么我必须切换到 postgres。

The*_*heo 31

Athena 确实不是低延迟数据存储。您很少会看到低于一秒的响应时间,而且通常会更长。在一般情况下,Athena 不适合作为 API 的后端,但这当然取决于它是哪种 API。如果它是某种分析服务,也许用户不期望亚秒响应时间?我已经构建了使用 Athena 的 API,它们工作得非常好,但这些服务的响应时间预计以秒为单位(甚至被认为是快速的),我从 Athena 团队那里得到了帮助,以根据我们的工作负载调整我们的帐户。

要了解 Athena 为什么“慢”,我们可以剖析当您向 Athena 提交查询时会发生什么:

  1. 您的代码使用StartQueryExecutionAPI 调用启动查询
  2. Athena 服务接收查询,并将其放入队列中。如果您不走运,您的查询将在队列中等待一段时间
  3. 当有可用容量时,Athena 服务会从队列中提取您的查询并制定查询计划
  4. 查询计划需要从 Glue 目录加载表元数据,包括分区列表,用于查询中包含的所有表
  5. Athena 还列出了它从表和分区中获得的 S3 上的所有位置,以生成将要处理的文件的完整列表
  6. 然后该计划并行执行,并根据其复杂性分多个步骤执行
  7. 合并并行执行的结果,并将结果序列化为 CSV 并写入 S3
  8. 同时,您的代码使用GetQueryExecutionAPI 调用检查查询是否已完成,直到它收到表明执行已成功、失败或已取消的响应
  9. 如果执行成功,您的代码使用GetQueryResultsAPI 调用来检索结果的第一页
  10. 为了响应该 API 调用,Athena 从 S3 读取结果 CSV,对其进行反序列化,并将其序列化为 API 响应的 JSON
  11. 如果有超过 1000 行,最后的步骤将重复

Presto 专家可能会提供有关步骤 4-6 的更多详细信息,即使它们在 Athena 的 Presto 版本中可能略有修改。不过,细节对于这次讨论并不是很重要。

如果您对大量数据(数十 GB 或更多)运行查询,则总执行时间将取决于第 6 步。如果结果也很大,则 7 将是一个因素。

如果您的数据集很小,和/或涉及 S3 上的数千个文件,那么 4-5 将占主导地位。

以下是 Athena 查询永远不会很快的一些原因,即使它们不会触及 S3(例如SELECT NOW()):

  • 在您获得响应之前,至少会有三个 API 调用 a StartQueryExecution、 aGetQueryExecution和 a GetQueryResults,只是它们的往返时间 (RTT) 加起来会超过 100 毫秒。
  • 您很可能必须GetQueryExecution多次调用,并且调用之间的延迟将限制您发现查询成功的速度,例如,如果您每 100 毫秒调用一次,则平均会增加 100 毫秒 + RTT 的一半到总时间,因为平均而言,您会错过实际完成时间这么多。
  • Athena 将在将执行标记为成功之前将结果写入 S3,并且由于它生成单个 CSV 文件,因此这不是并行完成的。一个大的回应需要时间来写。
  • GetQueryResults必须从S3阅读CSV,分析它,并对其进行序列化JSON作为。后续页面必须在 CSV 中向前跳过,甚至可能更慢。
  • Athena 是一项多租户服务,所有客户都在争夺资源,当没有足够的可用资源时,您的查询将排队。

如果您想知道是什么影响了查询的性能,您可以使用ListQueryExecutionsAPI 调用来列出最近的查询执行 ID(我认为您最多可以返回 90 天),然后用于GetQueryExecution获取查询统计信息(请参阅文档QueryExecution.Statistics每个属性的含义)。通过这些信息,您可以确定您的慢查询是由于排队、执行还是进行 API 调用的开销(如果不是前两个,则可能是最后一个)。

您可以采取一些措施来减少一些延迟,但这些技巧不太可能将延迟降至次秒级:

  • 如果您查询大量使用针对此类事情优化的文件格式的数据,Parquet 几乎总是答案 - 并确保您的文件大小是最佳的,大约 100 MB。
  • 避免大量文件,避免深层次结构。理想情况下,每个分区只有一个或几个文件,并且不要在“子目录”(带斜杠的 S3 前缀)中组织文件,除了那些对应于分区的文件。
  • 避免在最晚运行查询,这是当其他人的预定作业运行时,每个小时的前几分钟都会出现严重的资源争用。
  • 跳过GetQueryExecution,直接从 S3 下载 CSV。该GetQueryExecution电话是方便,如果你想知道列的数据类型,但如果你已经知道,或者不关心,直接读取数据可以为您节省宝贵的一些几十毫秒。如果您需要列数据类型,您可以获得….csv.metadata与结果 CSV 一起写入的文件,它是未记录的 Protobuf 数据,请参阅此处此处了解更多信息。
  • 请 Athena 服务团队调整您的帐户。如果没有更高级别的支持,这可能不是您可以获得的,我真的不知道这其中的政治因素,您需要先与您的客户经理交谈。

  • 反应很好。我们将外部来源的数据提取到 S3 中,以便在 Lambda 中实时查找,延迟为 2-3 秒,有时接近 10 秒。我想知道是否有一个解决方案是在 Lambda 中直接针对 S3 使用 Presto (或类似的),完全避免 Athena。我想 AWS S3 Select 也可以提供帮助。但我们需要在 S3 中找到正确的 CSV / JSON 段,因此我猜想需要 DynamoDB 来实现此索引或 EFS 中的某些索引。您知道该领域的解决方案吗? (3认同)
  • 我认为任何在 S3 上的数据上运行的通用查询引擎都不会为您提供一致的亚秒级延迟 - 您将需要为此定制的东西。我见过使用 Lambda 和 S3 构建的分析引擎,但它们都是针对 ~5 秒的目标,而不是 ~1 秒。不幸的是,这在很大程度上取决于很多事情。如果您想更详细地讨论它,您可以在 AWS Slack 开放指南或 AWS 开发人员 Slack 上找到我。 (3认同)