我的 Amazon Athena 查询因“HIVE_CANNOT_OPEN_SPLIT”错误而失败。
简短描述
Amazon Simple Storage Service(Amazon S3)存储桶只能支持存储桶中每秒每个前缀 3,500 个 PUT/COPY/POST/DELETE 或 5,500 个 GET/HEAD 请求。此硬性限制适用于一个 AWS 账户中的所有用户和服务。
默认情况下,Amazon S3 会自动扩展以支持高请求速率。当您的请求速率提高时,您的 S3 存储桶会自动分区以支持更高的请求速率。但是,如果超过请求阈值,则会收到“5xx Slow Down”错误。
例如,您对一个包含 10,000 个文件的前缀运行 Athena 查询。Athena 使用 GET/HEAD 请求尝试同时读取所有 10,000 个文件。但是,由于该前缀每秒最多仅支持 5,500 个 GET/HEAD 请求,因此您的 S3 请求会受到限制,您会收到“5xx Slow Down”错误。
解决方法
使用以下一种或多种方法,以免请求受限。
跨多个前缀分配 S3 对象和请求
为了帮助您在多个前缀之间分配对象和请求,请对数据进行分区。不要在一个 S3 前缀下存储大量文件。取而代之的是,使用多个前缀,在这些前缀之间分配 S3 对象。有关更多信息,请参阅在 Athena 中对数据进行分区。
例如,不要将所有文件都存储在 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),以将对象分布得更广。
减少每个前缀中的文件数量
当您查询包含大量小对象的 S3 存储桶时,您可能会收到“HIVE_CANNOT_OPEN_SPLIT”错误。例如,如果 S3 存储桶中有一个 100 MB 的文件,则 Athena 必须发出一个 GET 请求才能读取该文件。但是,如果有 1,000 个 100 KB 的文件,则 Athena 必须发出 1,000 个 GET 请求才能读取相同 100 MB 数据。此时,这些请求超过了 S3 的请求限制。
要减少 Amazon S3 请求的数量,请减少文件数量。例如,使用 S3DistCp 工具将大量小于 128 MB 的小文件合并为更少数量的大文件。有关更多信息,请参阅 Top 10 Performance Tuning Tips for Amazon Athena 中的 Optimize file sizes 部分。
命令示例:
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 不支持 Apache Parquet 文件连接。请改用 PySpark。有关更多信息,请参阅如何在 Amazon EMR 中连结 Parquet 文件?
检查您的 S3 存储桶的版本控制是否已激活
当您从使用版本控制的 S3 存储桶中删除对象时,Amazon S3 不会永久删除该对象。相反,Amazon S3 只会添加一个删除标记。如果您的 S3 存储桶中有许多文件都有删除标记,则可能会出现“HIVE_CANNOT_OPEN_SPLIT”错误。当您在开启了版本控制的存储桶上运行查询时,Athena 必须检查每个对象的不同版本。然后,在处理查询时,Athena 决定是否包含某个特定对象。
要解决此问题,请从您的 S3 存储桶中移除删除标记。要移除删除标记,请执行以下操作之一:
检查其他应用程序是否使用相同的 S3 前缀
使用 Amazon CloudWatch 5xxErrors 指标和 S3 服务器访问日志来检查其他应用程序在运行 Athena 查询时是否使用了相同的 S3 前缀。多个应用程序尝试从同一 S3 前缀读取数据可能会导致请求受限。不要安排应用程序同时访问相同前缀。此外,为 Athena 数据源和应用程序数据源使用不同的 S3 前缀。
为您的 S3 存储桶中的所有对象创建 CloudWatch 指标配置。使用这些指标来监控特定时间点特定前缀的 API 调用率指标。激活某个前缀的 S3 请求指标,以了解该前缀在某个时间点的整体 API 调用率。将此信息与 S3 服务器访问日志结合使用,查找使用 API 调用访问该前缀的应用程序。
要在单个分区中分割数据,也可以将数据分桶。有关更多信息,请参阅什么是分桶?
相关信息
如何解决来自 Amazon S3 的 HTTP 500 或 503 错误?
在 Athena 中进行故障排除
Athena 中的性能优化