排查 S3 批量操作问题 - Amazon Simple Storage Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

排查 S3 批量操作问题

Amazon S3 批量操作可让您对 Amazon S3 对象执行大规模操作。本指南有助于排查您可能遇到的常见问题。

要排查 S3 批量复制的问题,请参阅对复制进行问题排查

导致批量操作错误的失败主要有两种类型:

  1. API 失败:所请求的 API(例如 CreateJob)执行失败。

  2. 作业失败:初始 API 请求获得成功但作业失败,例如,由于清单或在清单中指定的对象的权限存在问题。

NoSuchJobException

类型:API 失败

当 S3 批量操作找不到指定的作业时,就会发生 NoSuchJobException。除了简单的作业到期之外,还可能在多种情况下发生此错误。常见原因包括以下各项:

  1. 作业到期:作业在达到终止状态(CompleteCancelledFailed)的 90 天后自动被删除。

  2. 作业 ID 不正确DescribeJobUpdateJobStatus 中使用的作业 ID 与 CreateJob 返回的 ID 不匹配。

  3. 错误的区域:尝试访问的作业所在的区域与创建该作业的区域不同。

  4. 账户错误:使用其它 Amazon 账户中的作业 ID。

  5. 作业 ID 格式错误:作业 ID 中存在拼写错误、多余字符或格式不正确。

  6. 计时问题:在完全注册作业之前,在创建后立即检查作业状态。

相关错误消息包括以下各项。

  1. No such job

  2. The specified job does not exist

防止 NoSuchJobException API 失败的最佳实践

  1. 立即存储作业 ID:在进行后续的 API 调用之前,先保存 CreateJob 响应中的作业 ID。

  2. 实现重试逻辑:在创建作业后立即检查作业状态时添加指数回退。

  3. 设置监控:创建 CloudWatch 警报以跟踪作业在 90 天到期之前的完成情况。有关详细信息,请参阅《Amazon CloudWatch 用户指南》中的使用 Amazon CloudWatch 警报

  4. 使用一致的区域:确保所有作业操作使用与创造作业相同的区域。

  5. 验证输入:在进行 API 调用之前检查作业 ID 格式。

作业何时到期

处于终止状态的作业将在 90 天后被自动删除。为避免丢失作业信息,请考虑以下事项。

  1. 在到期前下载完成报告:有关检索和存储作业结果的说明,请参阅

  2. 在您自己的系统中归档作业元数据:将关键的作业信息存储在数据库或监控系统中。

  3. 设置 90 天截止日期之前的自动通知:使用 Amazon EventBridge 创建在作业完成时触发通知的规则。有关更多信息,请参阅 Amazon S3 事件通知

NoSuchJobException 故障排除

  1. 使用以下命令验证作业是否存在于您的账户和区域中。

    aws s3control list-jobs --account-id 111122223333 --region us-east-1
  2. 使用以下命令在所有作业状态间进行搜索。可能的作业状态包括 ActiveCancelledCancellingCompleteCompletingFailedFailingNewPausedPausingPreparingReady、和 Suspended

    aws s3control list-jobs --account-id 111122223333 --job-statuses your-job-status
  3. 使用以下命令检查作业是否存在于您通常创建作业的其它区域中。

    aws s3control list-jobs --account-id 111122223333 --region job-region-1 aws s3control list-jobs --account-id 111122223333 --region job-region-2
  4. 验证作业 ID 格式。作业 ID 通常包含 36 个字符,例如 12345678-1234-1234-1234-123456789012。检查是否有多余的空格、缺少字符或是否存在区分大小写问题,并验证您使用的是 CreateJob 命令返回的完整作业 ID。

  5. 使用以下命令检查 CloudTrail 日志中是否存在作业创建事件。

    aws logs filter-log-events --log-group-name CloudTrail/S3BatchOperations \ --filter-pattern "{ $.eventName = CreateJob }" \ --start-time timestamp

AccessDeniedException

类型:API 失败

由于权限不足、操作不受支持或策略限制而阻止 S3 批量操作请求时,就会发生 AccessDeniedException。这是批量操作中最常见的错误之一。它具有以下常见原因:

  1. 缺少 IAM 权限:IAM 身份缺少批量操作 API 所需的权限。

  2. S3 权限不足:缺少访问源或目标存储桶和对象的权限。

  3. 作业执行角色问题:作业执行角色缺少执行指定操作的权限。

  4. 操作不受支持:尝试使用当前区域或存储桶类型不支持的操作。

  5. 跨账户访问问题:缺少跨账户访问存储桶或对象的权限。

  6. 基于资源的策略限制:存储桶策略或对象 ACL 阻止操作。

  7. 服务控制策略(SCP)限制:组织级策略阻止操作。

相关错误消息:

  1. Access Denied

  2. User: arn:aws:iam::account:user/username is not authorized to perform: s3:operation

  3. Cross-account pass role is not allowed

  4. The bucket policy does not allow the specified operation

防止 AccessDeniedException API 失败的最佳实践

  1. 使用最低权限原则:仅授予特定操作所需的最小权限。

  2. 在大型作业之前测试权限:在处理成千上万个对象之前,运行小型测试作业来验证权限。

  3. 使用 IAM 策略模拟器:在部署之前使用 IAM 策略模拟器测试策略。有关更多信息,请参阅《IAM 用户指南》中的使用 IAM 策略模拟器测试 IAM 策略

  4. 实施正确的跨账户设置:检查您的跨账户访问配置以了解跨账户作业配置。有关更多信息,请参阅《IAM 用户指南》中的 IAM 教程:使用 IAM 角色委托跨 Amazon 账户的访问权限

  5. 监控权限变更:针对可能影响批量操作的 IAM 策略修改设置 CloudTrail 提醒。

  6. 记录角色要求:清晰地记录每种作业类型的所需权限。

  7. 使用常用权限模板:使用权限示例和策略模板:

AccessDeniedException 故障排除

按照以下步骤系统化地识别和解决权限问题。

  1. 查看 S3 分批操作支持的操作以了解按区域支持的操作。确认目录存储桶操作仅适用于区域端点和可用区端点。验证存储桶的存储类别支持该操作。

  2. 使用以下命令确定您是否可以列出作业。

    aws s3control list-jobs --account-id 111122223333
  3. 使用以下命令检查请求身份的 IAM 权限。运行作业的账户需要以下权限:s3:CreateJobs3:DescribeJobs3:ListJobs-s3:UpdateJobPrioritys3:UpdateJobStatus-iam:PassRole

    aws sts get-caller-identity 111122223333
  4. 使用以下命令检查角色是否存在以及是否可代入。

    aws iam get-role --role-name role-name
  5. 使用以下命令查看角色的信任策略。运行作业的角色必须具有以下各项:

    1. 可让 batchoperations.s3.amazonaws.com 代入此角色的信任关系。

    2. 批量操作正在执行的操作(例如,对于标记操作为 s3:PutObjectTagging)。

    3. 对源存储桶和目标存储桶的访问权限。

    4. 读取清单文件的权限。

    5. 写入完成报告的权限。

    aws iam get-role --role-name role-name --query 'Role.AssumeRolePolicyDocument'
  6. 使用以下命令可重置对清单和源存储桶的访问权限。

    aws s3 ls s3://bucket-name
  7. 测试批量操作正在执行的操作。例如,如果批量操作执行标记操作,则在源存储桶中为示例对象添加标签。

  8. 查看存储桶策略,以了解是否存在可能拒绝该操作的策略。

    1. 如果使用旧版访问控制,请检查对象 ACL。

    2. 验证没有服务控制策略(SCP)阻止该操作。

    3. 如果使用 VPC 端点,请确认 VPC 端点策略支持批量操作。

  9. 通过以下命令使用 CloudTrail 来识别权限故障。

    aws logs filter-log-events --log-group-name CloudTrail/S3BatchOperations \ --filter-pattern "{ $.errorCode = AccessDenied }" \ --start-time timestamp

SlowDownError

类型:API 失败

当您的账户超过 S3 批量操作 API 的请求速率限制时,就会出现 SlowDownError 异常。这是一种节流机制,旨在防止服务因请求过多而不堪重负。它具有以下常见原因:

  1. API 请求频率高:在短时间内进行过多的 API 调用。

  2. 并行作业操作:多个应用程序或用户同时创建/管理作业。

  3. 没有速率限制的自动化脚本:未实施正确的回退策略的脚本。

  4. 过于频繁地轮询作业状态:检查作业状态的频率超出所需程度。

  5. 突增流量模式:在高峰处理时段,API 使用量突然激增。

  6. 区域容量限制:超过您的区域的已分配请求容量。

相关错误消息:

  1. SlowDown

  2. Please reduce your request rate

  3. Request rate exceeded

防止 SlowDownError API 失败的最佳实践

  1. 实施客户端速率限制:在应用程序中的 API 调用之间添加延迟。

  2. 使用指数回退以及抖动:随机化重试延迟,以避免出现惊群效应问题。

  3. 设置正确的重试逻辑:实施自动重试,并增加瞬态错误的延迟。

  4. 使用事件驱动的架构:将轮询替换为有关作业状态更改的 EventBridge 通知。

  5. 跨时间分配负载:将作业创建和状态检查错开在不同的时间段内进行。

  6. 监控速率限制并发出提醒:设置 CloudWatch 警报以便在接近限制时进行检测。

大多数 Amazon SDK 都包含针对速率限制错误的内置重试逻辑。按如下所示对它们进行配置:

  1. Amazon CLI:使用 cli-read-timeoutcli-connect-timeout 参数。

  2. 适用于 Python 的 Amazon SDK(Boto3):在客户端配置中配置重试模式和最大尝试次数。

  3. 适用于 Java 的 Amazon SDK:使用 RetryPolicyClientConfiguration 设置。

  4. 适用于 JavaScript 的 Amazon SDK:配置 maxRetriesretryDelayOptions

有关重试模式和最佳实践的更多信息,请参阅《Amazon Prescriptive Guidance》指南中的 Retry with backoff pattern

SlowDownError 故障排除

  1. 在代码中立即实现指数回退。

    例 :bash 中的指数回退
    for attempt in {1..5}; do if aws s3control describe-job --account-id 111122223333 --job-id job-id; then break else wait_time=$((2**attempt)) echo "Rate limited, waiting ${wait_time} seconds..." sleep $wait_time fi done
  2. 使用 CloudTrail 来识别高请求量的源。

    aws logs filter-log-events \ --log-group-name CloudTrail/S3BatchOperations \ --filter-pattern "{ $.eventName = CreateJob || $.eventName = DescribeJob }" \ --start-time timestamp \ --query 'events[*].[eventTime,sourceIPAddress,userIdentity.type,eventName]'
  3. 查看轮询频率。

    1. 对于处于活动状态的作业,请避免检查作业状态的频率超过每 30 秒一次。

    2. 尽可能使用作业完成通知而非轮询。

    3. 在轮询间隔中实施抖动,以避免同步的请求。

  4. 优化 API 使用模式。

    1. 如果可能,请批量执行多个操作。

    2. 使用 ListJobs 在一次调用中获取多个作业的状态。

    3. 缓存作业信息以减少冗余的 API 调用。

    4. 将作业创建操作分散到不同的时间,而不是同时创建许多作业。

  5. 针对 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 异常。它具有以下常见原因:

  1. 格式违规:缺少必需列、分隔符不正确或 CSV 结构的格式错误。

  2. 内容编码问题:字符编码、BOM 标记或非 UTF-8 字符不正确。

  3. 对象键问题:字符无效、URL 编码不正确或键超过长度限制。

  4. 大小限制:清单包含的对象数量超过了操作支持的数量。

  5. 版本 ID 格式错误:受版本控制的对象的版本 ID 无效或格式错误。

  6. ETag 格式问题:ETag 格式不正确,或需要 ETag 的操作缺少引号。

  7. 数据不一致:同一个清单中具有混合格式或列计数不一致。

相关错误消息:

  1. Required fields are missing in the schema: + missingFields

  2. Invalid Manifest Content

  3. The S3 Batch Operations job failed because it contains more keys than the maximum allowed in a single job

  4. Invalid object key format

  5. Manifest file is not properly formatted

  6. Invalid version ID format

  7. ETag format is invalid

防止 InvalidManifestContent 作业失败的最佳实践

  1. 上传前验证:在处理大型数据集之前,使用小型作业测试清单格式。

  2. 使用一致的编码:对于清单文件,始终使用无 BOM 的 UTF-8 编码。

  3. 实施清单生成标准:为创建清单操作创建模板和验证过程。

  4. 正确地处理特殊字符:对包含特殊字符的对象键进行 URL 编码。

  5. 监控对象计数:跟踪清单大小并主动拆分大型作业。

  6. 验证对象存在:在将对象包括在清单中之前,先验证对象是否存在。

  7. 使用 Amazon 工具生成清单:利用 Amazon CLI s3api list-objects-v2 生成格式正确的对象列表。

常见清单问题和解决方案:

  1. 缺少必需列:确保清单包含适用于操作类型的所有必需列。最常见的缺失列是 Bucket 和 Key。

  2. CSV 格式不正确:使用逗号分隔符,确保所有行的列计数一致,并避免在字段中嵌入换行符。

  3. 对象键中的特殊字符:对包含空格、Unicode 字符或 XML 特殊字符(<、>、&、"、')的对象键进行 URL 编码。

  4. 大型清单文件:将超过操作限制的清单拆分为多个较小的清单并创建单独的作业。

  5. 版本 ID 无效:确保版本 ID 是格式正确的字母数字字符串。如果不需要版本 ID 列,请将其移除。

  6. 编码问题:将清单文件另存为无 BOM 的 UTF-8。避免通过可能更改编码的系统来复制清单。

有关详细的清单格式规范和示例,请参阅以下内容:

InvalidManifestContent 故障排除

  1. 下载并检查清单文件。手动验证清单是否符合格式要求:

    1. 使用逗号分隔符的 CSV 格式。

    2. 无 BOM 的 UTF-8 编码。

    3. 所有行的列数一致。

    4. 没有空行或尾随空格。

    5. 如果对象键包含特殊字符,已对对象键进行正确的 URL 编码。

    使用以下命令下载作业清单文件。

    aws s3 cp s3://amzn-s3-demo-bucket1/manifest-key ./manifest.csv
  2. 检查您的操作所需的列:

    1. 所有操作:BucketKey

    2. 复制操作:VersionId(可选)

    3. 还原操作:VersionId(可选)

    4. 替换标签操作:无需其它列。

    5. 替换 ACL 操作:无需其它列。

    6. 启动还原:VersionId(可选)

  3. 检查对象计数限制:

    1. 复制:最多 10 亿个对象。

    2. 删除:最多 10 亿个对象。

    3. 还原:最多 10 亿个对象。

    4. 添加标签:最多 10 亿个对象。

    5. ACL:最多 10 亿个对象。

  4. 使用原始清单中的几个对象创建测试清单。

  5. 使用以下命令检查清单中的对象示例是否存在。

    aws s3 ls s3://amzn-s3-demo-bucket1/object-key
  6. 检查作业失败详细信息,并在作业描述中查看失败原因和任何特定错误详情。

    aws s3control describe-job --account-id 111122223333 --job-id job-id