计划是从 aws 数据交换获取数据,将其移动到 s3 存储桶,然后通过 aws athena 查询数据 api。一切正常,只是感觉有点慢。
无论数据集还是查询,athena 响应时间都不能低于 2 秒。对于 API 来说,这已经太多了。我检查了最佳实践,但似乎这些也都超过 2 秒。
所以我的问题是:
2 秒是 athena 的最短响应时间吗?
如果是这样,那么我必须切换到 postgres。
Athena 确实不是一个低延迟的数据存储。您很少会看到响应时间低于一秒,而且通常会相当长。一般情况下,Athena 不适合作为 API 的后端,但这当然取决于它是什么类型的 API。如果它是某种分析服务,也许用户不期望亚秒级响应时间?我已经构建了使用 Athena 的 API,效果非常好,但这些服务的响应时间预计以秒为单位(甚至被认为很快),并且我得到了 Athena 团队的帮助,根据我们的工作负载调整我们的帐户。
要理解 Athena 为什么“慢”,我们可以剖析当您向 Athena 提交查询时会发生什么:
- 您的代码使用以下方式启动查询
StartQueryExecution
API调用
- Athena 服务接收查询,并将其放入队列中。如果你不幸运,你的查询将在队列中等待一段时间
- 当有可用容量时,Athena 服务从队列中获取您的查询并制定查询计划
- 查询计划需要从 Glue 目录加载表元数据,包括查询中包含的所有表的分区列表
- Athena 还列出了从表和分区获取的 S3 上的所有位置,以生成将要处理的文件的完整列表
- 然后,根据计划的复杂性,分多个步骤并行执行该计划
- 并行执行的结果被合并,结果被序列化为 CSV 并写入 S3
- 同时,您的代码使用以下命令检查查询是否已完成
GetQueryExecution
API 调用,直到收到执行已成功、失败或已取消的响应
- 如果执行成功,您的代码将使用
GetQueryResults
API 调用以检索结果的第一页
- 为了响应该 API 调用,Athena 从 S3 读取结果 CSV,将其反序列化,然后将其序列化为 API 响应的 JSON
- 如果行数超过 1000 行,则将重复最后的步骤
Presto 专家可能会提供有关步骤 4-6 的更多详细信息,尽管它们可能在 Athena 版本的 Presto 中进行了一些修改。不过,细节对于本次讨论来说并不是很重要。
如果您对大量数据(数十GB或更多)运行查询,则总执行时间将由步骤6主导。如果结果也很大,则7将是一个因素。
如果您的数据集很小,和/或涉及 S3 上的数千个文件,那么 4-5 将占据主导地位。
以下是 Athena 查询永远不会很快的一些原因,即使它们不会触及 S3(例如SELECT NOW()
):
- 在获得响应之前,至少会进行 3 个 API 调用,一个
StartQueryExecution
, a GetQueryExecution
, and a GetQueryResults
,仅它们的往返时间 (RTT) 就会加起来超过 100 毫秒。
- 您很可能需要致电
GetQueryExecution
多次,并且调用之间的延迟将限制您发现查询成功的速度,例如如果您每 100 毫秒调用一次,您平均会在总时间中添加 100 毫秒 + RTT 的一半,因为平均而言您会错过实际完成时间这么多。
- Athena 会将结果写入 S3,然后将执行标记为成功,并且由于它生成单个 CSV 文件,因此这不是并行完成的。一个大的回应需要时间来写。
- The
GetQueryResults
必须从 S3 读取 CSV,解析它并将其序列化为 JSON。后续页面必须在 CSV 中向前跳过,并且速度可能会更慢。
- Athena 是一项多租户服务,所有客户都在争夺资源,当没有足够的可用资源时,您的查询将排队。
如果您想知道影响查询性能的因素,您可以使用ListQueryExecutions
API调用列出最近的查询执行ID(我认为你最多可以回溯90天),然后使用GetQueryExecution
获取查询统计信息(请参阅的文档QueryExecution.Statistics https://docs.aws.amazon.com/athena/latest/APIReference/API_QueryExecutionStatistics.html每个属性的含义)。通过这些信息,您可以确定查询缓慢是否是由于排队、执行或 API 调用的开销造成的(如果不是前两个,很可能是最后一个)。
您可以采取一些措施来减少延迟,但这些提示不太可能让您将延迟降至亚秒级:
- 如果您查询大量数据使用针对此类事情进行了优化的文件格式,Parquet 几乎总是答案 - 并且还要确保您的文件大小是最佳的,大约 100 MB。
- 避免大量文件,并避免深层层次结构。理想情况下,每个分区只有一个或几个文件,并且不要将文件组织在“子目录”(带有斜杠的 S3 前缀)中,除了与分区对应的文件之外。
- 避免在整点运行查询,这是其他人的计划作业运行的时间,每个小时的前几分钟都会出现严重的资源争用。
- Skip
GetQueryExecution
,直接从S3下载CSV。这GetQueryExecution
如果您想知道列的数据类型,则调用很方便,但如果您已经知道,或者不关心,直接读取数据可以为您节省一些宝贵的数十毫秒。如果您需要列数据类型,您可以获得….csv.metadata
与结果 CSV 一起写入的文件,它是未记录的 Protobuf 数据,请参阅here https://stackoverflow.com/questions/55991018/whats-the-data-format-of-athenas-csv-metadata-files and here https://github.com/burtcorp/athena-jdbc/blob/master/src/main/java/io/burt/athena/result/AthenaMetaDataParser.java了解更多信息。
- 请 Athena 服务团队调整您的帐户。如果没有更高级别的支持,这可能不是您可以获得的,我真的不知道这其中的政治因素,您需要首先与您的客户经理交谈。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)