如何解析 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 存储桶中移除删除标记。您可以通过执行以下任一操作来移除删除标记:
- 手动删除删除标记:使用 ListObjectVersions API 列出有关 S3 存储桶中所有版本对象的元数据。从返回的元数据中,找到对象的 versionID,然后永久删除删除标记。
- 设置生命周期配置以删除删除标记:您可以使用 S3 生命周期策略定义希望 Amazon S3 在对象生命周期内执行的操作。
检查其他应用程序是否使用相同的 S3 前缀
使用 Amazon CloudWatch 5xxErrors 指标和 S3 服务器访问日志检查其他应用程序(例如 EMR 上的 Hive、Spark 或 AWS Glue)是否在运行 Athena 查询时使用相同的 S3 前缀。多个应用程序尝试从同一 S3 前缀读取数据可能会导致请求受到限制、查询失败并返回“速度下降”错误。避免安排多个应用程序同时访问同一前缀。此外,对 Athena 数据源和应用程序数据源使用不同的 S3 前缀。
您可以为 S3 存储桶中的所有对象创建 CloudWatch 指标配置。使用这些指标可以在特定时间点监视特定前缀的 API 调用率指标。为前缀启用 S3 请求指标有助于了解特定时间点前缀的总体 API 命中率。您可以将此信息与 S3 服务器访问日志结合使用,以查找哪个应用程序正在对该前缀进行 API 调用。