【问题标题】:AWS Athena too slow for an api?AWS Athena 对于 api 来说太慢了?
【发布时间】:2020-08-08 06:22:50
【问题描述】:

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

无论是数据集还是查询,我的雅典娜响应时间都不能低于 2 秒。这对于 API 来说意义重大。我检查了最佳实践,但似乎也超过 2 秒。

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

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

【问题讨论】:

  • 我们使用athena查询一些访问日志,自定义日志调试一些应用。我不确定它是否适合生产端点。如文件所述; query services like Amazon Athena make it easy to run interactive queries against data directly in Amazon S3 without worrying about formatting data or managing infrastructure. For example, Athena is great if you just need to run a quick query on some web logs to troubleshoot a performance issue on your site.
  • aws.amazon.com/athena/faqs/…你可以在这里查看。
  • Amazon Athena 的惊人之处在于它能够查看大量数据而无需将其加载到数据库中。但是,如果您正在寻求快速响应时间,那么您将希望使用数据库,而不是查询引擎。
  • 没有看到任何地方提到它,但 Athena 的并发执行限制相当低。软限制从 25 个并发查询开始,但可以增加。最重要的是,StartExecution 的软限制为 20 r/s,最高可达 80 r/s(因此,如果您正在为超过 20 个请求/秒提供服务,其中包括 Athena 查询,那么您可能会在尝试启动查询时遇到问题)

标签: amazon-web-services amazon-athena


【解决方案1】:

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

要了解 Athena 为何“慢”,我们可以剖析您向 Athena 提交查询时发生的情况:

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

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

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

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

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

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

如果您想知道影响查询性能的因素,您可以使用ListQueryExecutions API 调用列出最近的查询执行 ID(我认为您最多可以返回 90 天),然后使用 GetQueryExecution获取查询统计信息(请参阅the documentation for QueryExecution.Statistics 了解每个属性的含义)。有了这些信息,您可以确定您的慢查询是因为排队、执行还是 API 调用的开销(如果不是前两个,很可能是最后一个)。

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

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

【讨论】:

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