排查 S3 批量操作问题
Amazon S3 批量操作可让您对 Amazon S3 对象执行大规模操作。本指南有助于排查您可能遇到的常见问题。
要排查 S3 批量复制的问题,请参阅对复制进行问题排查。
导致批量操作错误的失败主要有两种类型:
-
API 失败:所请求的 API(例如
CreateJob)执行失败。 -
作业失败:初始 API 请求获得成功但作业失败,例如,由于清单或在清单中指定的对象的权限存在问题。
NoSuchJobException
类型:API 失败
当 S3 批量操作找不到指定的作业时,就会发生 NoSuchJobException。除了简单的作业到期之外,还可能在多种情况下发生此错误。常见原因包括以下各项:
作业到期:作业在达到终止状态(
Complete、Cancelled或Failed)的 90 天后自动被删除。作业 ID 不正确:
DescribeJob或UpdateJobStatus中使用的作业 ID 与CreateJob返回的 ID 不匹配。错误的区域:尝试访问的作业所在的区域与创建该作业的区域不同。
账户错误:使用其它 Amazon 账户中的作业 ID。
作业 ID 格式错误:作业 ID 中存在拼写错误、多余字符或格式不正确。
计时问题:在完全注册作业之前,在创建后立即检查作业状态。
相关错误消息包括以下各项。
No such jobThe specified job does not exist
防止 NoSuchJobException API 失败的最佳实践
立即存储作业 ID:在进行后续的 API 调用之前,先保存
CreateJob响应中的作业 ID。实现重试逻辑:在创建作业后立即检查作业状态时添加指数回退。
设置监控:创建 CloudWatch 警报以跟踪作业在 90 天到期之前的完成情况。有关详细信息,请参阅《Amazon CloudWatch 用户指南》中的使用 Amazon CloudWatch 警报。
使用一致的区域:确保所有作业操作使用与创造作业相同的区域。
验证输入:在进行 API 调用之前检查作业 ID 格式。
作业何时到期
处于终止状态的作业将在 90 天后被自动删除。为避免丢失作业信息,请考虑以下事项。
在您自己的系统中归档作业元数据:将关键的作业信息存储在数据库或监控系统中。
设置 90 天截止日期之前的自动通知:使用 Amazon EventBridge 创建在作业完成时触发通知的规则。有关更多信息,请参阅 Amazon S3 事件通知。
NoSuchJobException 故障排除
使用以下命令验证作业是否存在于您的账户和区域中。
aws s3control list-jobs --account-id111122223333--regionus-east-1使用以下命令在所有作业状态间进行搜索。可能的作业状态包括
Active、Cancelled、Cancelling、Complete、Completing、Failed、Failing、New、Paused、Pausing、Preparing、Ready、和Suspended。aws s3control list-jobs --account-id111122223333--job-statusesyour-job-status使用以下命令检查作业是否存在于您通常创建作业的其它区域中。
aws s3control list-jobs --account-id111122223333--regionjob-region-1aws s3control list-jobs --account-id111122223333--regionjob-region-2-
验证作业 ID 格式。作业 ID 通常包含 36 个字符,例如
12345678-1234-1234-1234-123456789012。检查是否有多余的空格、缺少字符或是否存在区分大小写问题,并验证您使用的是CreateJob命令返回的完整作业 ID。 -
使用以下命令检查 CloudTrail 日志中是否存在作业创建事件。
aws logs filter-log-events --log-group-name CloudTrail/S3BatchOperations \ --filter-pattern "{ $.eventName = CreateJob }" \ --start-timetimestamp
AccessDeniedException
类型:API 失败
由于权限不足、操作不受支持或策略限制而阻止 S3 批量操作请求时,就会发生 AccessDeniedException。这是批量操作中最常见的错误之一。它具有以下常见原因:
缺少 IAM 权限:IAM 身份缺少批量操作 API 所需的权限。
S3 权限不足:缺少访问源或目标存储桶和对象的权限。
作业执行角色问题:作业执行角色缺少执行指定操作的权限。
操作不受支持:尝试使用当前区域或存储桶类型不支持的操作。
跨账户访问问题:缺少跨账户访问存储桶或对象的权限。
基于资源的策略限制:存储桶策略或对象 ACL 阻止操作。
服务控制策略(SCP)限制:组织级策略阻止操作。
相关错误消息:
Access DeniedUser: arn:aws:iam::account:user/username is not authorized to perform: s3:operationCross-account pass role is not allowedThe bucket policy does not allow the specified operation
防止 AccessDeniedException API 失败的最佳实践
使用最低权限原则:仅授予特定操作所需的最小权限。
在大型作业之前测试权限:在处理成千上万个对象之前,运行小型测试作业来验证权限。
使用 IAM 策略模拟器:在部署之前使用 IAM 策略模拟器测试策略。有关更多信息,请参阅《IAM 用户指南》中的使用 IAM 策略模拟器测试 IAM 策略。
实施正确的跨账户设置:检查您的跨账户访问配置以了解跨账户作业配置。有关更多信息,请参阅《IAM 用户指南》中的 IAM 教程:使用 IAM 角色委托跨 Amazon 账户的访问权限。
监控权限变更:针对可能影响批量操作的 IAM 策略修改设置 CloudTrail 提醒。
记录角色要求:清晰地记录每种作业类型的所需权限。
使用常用权限模板:使用权限示例和策略模板:
《IAM 用户指南》中的 IAM 中的跨账户资源。
《Amazon PrivateLink Guide》中的 Control access to VPC endpoints using endpoint policies。
AccessDeniedException 故障排除
按照以下步骤系统化地识别和解决权限问题。
查看 S3 分批操作支持的操作以了解按区域支持的操作。确认目录存储桶操作仅适用于区域端点和可用区端点。验证存储桶的存储类别支持该操作。
使用以下命令确定您是否可以列出作业。
aws s3control list-jobs --account-id111122223333使用以下命令检查请求身份的 IAM 权限。运行作业的账户需要以下权限:
s3:CreateJob、s3:DescribeJob、s3:ListJobs-s3:UpdateJobPriority、s3:UpdateJobStatus-iam:PassRole。aws sts get-caller-identity111122223333使用以下命令检查角色是否存在以及是否可代入。
aws iam get-role --role-namerole-name-
使用以下命令查看角色的信任策略。运行作业的角色必须具有以下各项:
可让
batchoperations.s3.amazonaws.com代入此角色的信任关系。批量操作正在执行的操作(例如,对于标记操作为
s3:PutObjectTagging)。对源存储桶和目标存储桶的访问权限。
读取清单文件的权限。
写入完成报告的权限。
aws iam get-role --role-namerole-name--query 'Role.AssumeRolePolicyDocument' 使用以下命令可重置对清单和源存储桶的访问权限。
aws s3 ls s3://bucket-name-
测试批量操作正在执行的操作。例如,如果批量操作执行标记操作,则在源存储桶中为示例对象添加标签。
查看存储桶策略,以了解是否存在可能拒绝该操作的策略。
如果使用旧版访问控制,请检查对象 ACL。
验证没有服务控制策略(SCP)阻止该操作。
如果使用 VPC 端点,请确认 VPC 端点策略支持批量操作。
通过以下命令使用 CloudTrail 来识别权限故障。
aws logs filter-log-events --log-group-name CloudTrail/S3BatchOperations \ --filter-pattern "{ $.errorCode = AccessDenied }" \ --start-timetimestamp
SlowDownError
类型:API 失败
当您的账户超过 S3 批量操作 API 的请求速率限制时,就会出现 SlowDownError 异常。这是一种节流机制,旨在防止服务因请求过多而不堪重负。它具有以下常见原因:
API 请求频率高:在短时间内进行过多的 API 调用。
并行作业操作:多个应用程序或用户同时创建/管理作业。
没有速率限制的自动化脚本:未实施正确的回退策略的脚本。
过于频繁地轮询作业状态:检查作业状态的频率超出所需程度。
突增流量模式:在高峰处理时段,API 使用量突然激增。
区域容量限制:超过您的区域的已分配请求容量。
相关错误消息:
SlowDownPlease reduce your request rateRequest rate exceeded
防止 SlowDownError API 失败的最佳实践
实施客户端速率限制:在应用程序中的 API 调用之间添加延迟。
使用指数回退以及抖动:随机化重试延迟,以避免出现惊群效应问题。
设置正确的重试逻辑:实施自动重试,并增加瞬态错误的延迟。
使用事件驱动的架构:将轮询替换为有关作业状态更改的 EventBridge 通知。
跨时间分配负载:将作业创建和状态检查错开在不同的时间段内进行。
监控速率限制并发出提醒:设置 CloudWatch 警报以便在接近限制时进行检测。
大多数 Amazon SDK 都包含针对速率限制错误的内置重试逻辑。按如下所示对它们进行配置:
Amazon CLI:使用
cli-read-timeout和cli-connect-timeout参数。适用于 Python 的 Amazon SDK(Boto3):在客户端配置中配置重试模式和最大尝试次数。
适用于 Java 的 Amazon SDK:使用
RetryPolicy和ClientConfiguration设置。适用于 JavaScript 的 Amazon SDK:配置
maxRetries和retryDelayOptions。
有关重试模式和最佳实践的更多信息,请参阅《Amazon Prescriptive Guidance》指南中的 Retry with backoff pattern。
SlowDownError 故障排除
在代码中立即实现指数回退。
例 :bash 中的指数回退
for attempt in {1..5}; do if aws s3control describe-job --account-id111122223333--job-idjob-id; then break else wait_time=$((2**attempt)) echo "Rate limited, waiting ${wait_time} seconds..." sleep $wait_time fi done-
使用 CloudTrail 来识别高请求量的源。
aws logs filter-log-events \ --log-group-name CloudTrail/S3BatchOperations \ --filter-pattern "{ $.eventName = CreateJob || $.eventName = DescribeJob }" \ --start-timetimestamp\ --query 'events[*].[eventTime,sourceIPAddress,userIdentity.type,eventName]' 查看轮询频率。
对于处于活动状态的作业,请避免检查作业状态的频率超过每 30 秒一次。
尽可能使用作业完成通知而非轮询。
在轮询间隔中实施抖动,以避免同步的请求。
-
优化 API 使用模式。
如果可能,请批量执行多个操作。
使用
ListJobs在一次调用中获取多个作业的状态。缓存作业信息以减少冗余的 API 调用。
将作业创建操作分散到不同的时间,而不是同时创建许多作业。
-
针对 API 调用使用 CloudWatch 指标来监控请求模式。
aws logs put-metric-filter \ --log-group-name CloudTrail/S3BatchOperations \ --filter-name S3BatchOpsAPICallCount \ --filter-pattern "{ $.eventSource = s3.amazonaws.com && $.eventName = CreateJob }" \ --metric-transformations \ metricName=S3BatchOpsAPICalls,metricNamespace=Custom/S3BatchOps,metricValue=1
InvalidManifestContent
类型:作业失败
当清单文件格式、内容或结构出现问题而导致 S3 批量操作无法处理作业时,就会出现 InvalidManifestContent 异常。它具有以下常见原因:
格式违规:缺少必需列、分隔符不正确或 CSV 结构的格式错误。
内容编码问题:字符编码、BOM 标记或非 UTF-8 字符不正确。
对象键问题:字符无效、URL 编码不正确或键超过长度限制。
大小限制:清单包含的对象数量超过了操作支持的数量。
版本 ID 格式错误:受版本控制的对象的版本 ID 无效或格式错误。
ETag 格式问题:ETag 格式不正确,或需要 ETag 的操作缺少引号。
数据不一致:同一个清单中具有混合格式或列计数不一致。
相关错误消息:
Required fields are missing in the schema: + missingFieldsInvalid Manifest ContentThe S3 Batch Operations job failed because it contains more keys than the maximum allowed in a single jobInvalid object key formatManifest file is not properly formattedInvalid version ID formatETag format is invalid
防止 InvalidManifestContent 作业失败的最佳实践
上传前验证:在处理大型数据集之前,使用小型作业测试清单格式。
使用一致的编码:对于清单文件,始终使用无 BOM 的 UTF-8 编码。
实施清单生成标准:为创建清单操作创建模板和验证过程。
正确地处理特殊字符:对包含特殊字符的对象键进行 URL 编码。
监控对象计数:跟踪清单大小并主动拆分大型作业。
验证对象存在:在将对象包括在清单中之前,先验证对象是否存在。
使用 Amazon 工具生成清单:利用 Amazon CLI
s3api list-objects-v2生成格式正确的对象列表。
常见清单问题和解决方案:
缺少必需列:确保清单包含适用于操作类型的所有必需列。最常见的缺失列是 Bucket 和 Key。
CSV 格式不正确:使用逗号分隔符,确保所有行的列计数一致,并避免在字段中嵌入换行符。
对象键中的特殊字符:对包含空格、Unicode 字符或 XML 特殊字符(<、>、&、"、')的对象键进行 URL 编码。
大型清单文件:将超过操作限制的清单拆分为多个较小的清单并创建单独的作业。
版本 ID 无效:确保版本 ID 是格式正确的字母数字字符串。如果不需要版本 ID 列,请将其移除。
编码问题:将清单文件另存为无 BOM 的 UTF-8。避免通过可能更改编码的系统来复制清单。
有关详细的清单格式规范和示例,请参阅以下内容:
InvalidManifestContent 故障排除
下载并检查清单文件。手动验证清单是否符合格式要求:
使用逗号分隔符的 CSV 格式。
无 BOM 的 UTF-8 编码。
所有行的列数一致。
没有空行或尾随空格。
如果对象键包含特殊字符,已对对象键进行正确的 URL 编码。
使用以下命令下载作业清单文件。
aws s3 cp s3://amzn-s3-demo-bucket1/manifest-key./manifest.csv-
检查您的操作所需的列:
所有操作:
Bucket、Key复制操作:
VersionId(可选)还原操作:
VersionId(可选)替换标签操作:无需其它列。
替换 ACL 操作:无需其它列。
启动还原:
VersionId(可选)
-
检查对象计数限制:
复制:最多 10 亿个对象。
删除:最多 10 亿个对象。
还原:最多 10 亿个对象。
添加标签:最多 10 亿个对象。
ACL:最多 10 亿个对象。
-
使用原始清单中的几个对象创建测试清单。
-
使用以下命令检查清单中的对象示例是否存在。
aws s3 ls s3://amzn-s3-demo-bucket1/object-key -
检查作业失败详细信息,并在作业描述中查看失败原因和任何特定错误详情。
aws s3control describe-job --account-id111122223333--job-idjob-id