如何解析 Athena 中的“HIVE_CANNOT_OPEN_SPLIT:打开 Hive 拆分 s3://awsdoc-example-bucket/ 时出错:速度下降(服务:Amazon S3;状态代码:503;错误代码:503 速度下降;”错误?

上次更新日期:2021 年 5 月 4 日

我的 Amazon Athena 查询失败,并出现以下其中一项错误:

“HIVE_CANNOT_OPEN_SPLIT:打开 Hive 拆分 s3://awsdoc-example-bucket/date=2020-05-29/ingest_date=2020-04-25/part-00000.snappy.parquet (offset=0, length=18614) 时出错:速度下降(服务:Amazon S3;状态代码:503;错误代码:503 速度下降;”

-或者-

“未知故障(状态代码 = 1003,java.sql.SQLException: [Simba][AthenaJDBC](100071) AWS Athena 引发了错误 client.HIVE_CANNOT_OPEN_SPLIT:打开 Hive 拆分 s3://awsdoc-example-bucket/date=2020-05-29/ingest_date=2020-04-25/part-00000.snappy.parquet (offset=0, length=18614) 时出错:速度下降(服务:Amazon S3;状态代码:503;错误代码:503 速度下降;”

简短描述

Amazon Simple Storage Service (Amazon S3) 存储桶可以在存储桶中每个前缀每秒处理 3500 个 PUT/COPY/POST/DELETE 请求或 5500 个 GET/HEAD 请求。超过此请求阈值时会发生这类错误。此限制是对账户中所有用户和服务的合并限制。

默认情况下,Amazon S3 会自动扩展以支持非常高的请求速率。当请求速率扩大时,S3 存储桶会自动分区以支持更高的请求速率。但是,如果超过请求阈值,您将会收到 5xx 错误,要求您放慢速度或稍后再试。

例如,前缀 s3://my-athena-bucket/month=jan/ 只能支持每秒 3500 个 PUT/COPY/POST/DELETE 请求或每秒 5500 个 GET/HEAD 请求。如果您在此前缀中有 10000 个文件,并且对此前缀运行 Athena 查询,则会收到 503 速度下降错误。这是因为 Athena 尝试使用 GET/HEAD 请求同时读取该前缀上的所有 10000 个文件,但前缀最多只能支持每秒 5500 个 GET/HEAD 请求。这可能会导致您的 S3 请求受到限制并引发“503 速度下降”错误。

解决方法

使用以下一种或几种方法来防止发生请求限制:

在多个前缀之间分配 S3 对象和请求

对数据进行分区可以帮助在多个前缀之间分配对象和请求。避免将许多文件存储在单个 S3 前缀下。考虑使用多个前缀,以便在这些前缀之间分配 S3 对象。通过对数据进行分区,您可以减少每个查询扫描的数据量。有关更多信息,请参阅对数据进行分区

例如,不是将所有文件存储在 s3://my-athena-bucket/my-athena-data-files 下,而是对数据进行分区并分别存储在以下各个前缀下:

s3://my-athena-bucket/jan

s3://my-athena-bucket/feb

s3://my-athena-bucket/mar

这些文件中的数据可以进一步分区,以增加分配的对象数量(例如:s3://my-athena-bucket/jan/01)。

有关决定 Athena 分区文件夹结构的更多信息,请参阅 Amazon S3 性能技巧与诀窍

减少每个前缀中的文件数

当您查询包含大量小对象的 S3 存储桶时,可能会出现此错误。例如,如果 S3 存储桶中有一个 100 MB 的文件,那么 Athena 只要发出 1 个 GET 请求就能读取该文件。但是,如果有 1000 个大小为 100 KB 的文件,那么 Athena 需要发出 1000 个 GET 请求才能读取相同的 100 MB 数据。这会导致请求超过 S3 请求限制。

为了减少 Amazon S3 请求的数量,请减少文件的数量。例如,使用 S3DistCp 工具将大量小文件(小于 128 MB)合并成少量大文件。有关更多信息,请参阅 Amazon Athena 的十大性能优化技巧并回顾 4.优化文件大小部分。

示例:

s3-dist-cp --src=s3://my_athena_bucket_source/smallfiles/ --dest=s3://my_athena_bucket_target/largefiles/ --groupBy='.*(.csv)'
请务必在上述命令中替换以下内容:
  • 用 my_athena_bucket_source 替换存放小文件的源 S3 存储桶。
  • 用 my_athena_bucket_target 替换用于存储输出的目标 S3 存储桶。

您可以使用 groupBy 选项将小文件聚合为您选择的大小的少量大文件。这可以帮助您优化查询性能和成本。

注意:S3DistCp 不支持串联 Parquet 文件。因此应使用 PySpark。有关更多信息,请参阅如何在 Amazon EMR 中串联 Parquet 文件?

检查 S3 存储桶是否启用了版本控制

当您从启用版本控制的存储桶中删除对象时,Amazon S3 会插入删除标记,而不是永久删除对象。如果 S3 存储桶中有许多带有删除标记的文件,则可能会出现此错误。当您对启用版本控制的存储桶运行查询时,Athena 必须检查每个对象的不同版本。然后,Athena 决定在查询处理过程中是否要包括特定对象。

要解决此错误,请考虑从 S3 存储桶中移除删除标记。您可以通过执行以下任一操作来移除删除标记:

检查其他应用程序是否使用相同的 S3 前缀

使用 Amazon CloudWatch 5xxErrors 指标S3 服务器访问日志检查其他应用程序(例如 EMR 上的 Hive、Spark 或 AWS Glue)是否在运行 Athena 查询时使用相同的 S3 前缀。多个应用程序尝试从同一 S3 前缀读取数据可能会导致请求受到限制、查询失败并返回“速度下降”错误。避免安排多个应用程序同时访问同一前缀。此外,对 Athena 数据源和应用程序数据源使用不同的 S3 前缀。

您可以为 S3 存储桶中的所有对象创建 CloudWatch 指标配置。使用这些指标可以在特定时间点监视特定前缀的 API 调用率指标。为前缀启用 S3 请求指标有助于了解特定时间点前缀的总体 API 命中率。您可以将此信息与 S3 服务器访问日志结合使用,以查找哪个应用程序正在对该前缀进行 API 调用。