亚马逊AWS官方博客

EMR和S3的跨区域应急备份恢复方案之二:亿级数据文件批量筛选恢复

序言

在跨区域灾难恢复场景中,恢复速度往往决定业务能否在关键时刻保持连续性。对于快时尚电商这样的高数据密度业务而言,S3 中动辄亿级数据文件不仅构成核心资产,也意味着一旦需要恢复,延迟过长会迅速放大为运营风险。在亿级数据文件的恢复任务中,传统依赖人工脚本或 Inventory 报告的方式往往存在准备周期长、处理效率低等一系列问题,使它们难以承担真正的应急恢复需求。企业经常需要根据对象的年龄、大小或类型等条件,筛选并处理特定子集的数据,当数据量呈指数级增长时,这一挑战也随之放大。在系统面临灾难恢复等关键需求时,能够在亿级数据文件当中,快速定位和处理相关对象至关重要,但传统方法通常需要数小时甚至数天的准备时间,才能真正开始执行处理任务。

然而,Amazon S3 Batch Operations 提供了一条截然不同的路径,以一次请求执行高达 200 亿个对象的批量操作,并在灾难恢复场景中以分钟级响应速度直接介入恢复流程。无论是跨区域复制数据、恢复 Archive/Glacier 归档对象、应用新策略、批量更新元数据,还是为上层的 EMR 任务重建输入目录结构,Amazon S3 Batch Operations 都能以企业级吞吐能力确保恢复过程迅速、可控而无需繁琐的定制开发。

早期传统串行处理模式,归档数据的恢复操作主要依赖两种方式,一是通过 S3 Inventory 报告或手动 CSV 生成 manifest 文件,但首次生成 Inventory 可能需要 24–48 小时;二是编写自定义脚本通过 aws s3api list-objects 逐个列出和处理对象,虽然避免了等待 Inventory 的时间,但面临串行处理效率低下、API 调用限制、单点故障风险等问题,在处理亿级归档数据文件时同样无法满足应急恢复的时效要求。这些传统方式与”应急恢复”的诉求完全相悖。为了彻底消除这一瓶颈,Amazon S3 推出了 manifest generator 功能,使用户能够直接基于 prefix、时间、存储类型等条件动态实时的生成对象列表。这意味着不再等待,不再预生成,不再依赖外部工具,恢复任务可以在需求出现的那一刻立即启动。

在本文中,我们将展示如何利用 S3 Batch Operations 搭配 manifest generator 来构建一种真正符合应急恢复”定义的跨区域 S3 恢复方法

  • 无需 Inventory 报告
  • 无需提前准备
  • 基于条件即时筛选
  • 快速生成 manifest
  • 立刻执行批处理任务

通过这些技术,传统需等待数小时到数天的准备流程被压缩为即时响应,从而使企业能够在突发事件下以最高效率,从归档存储中快速筛选并提取所需的关键数据文件,在运营需求出现时立即启动带有动态过滤的 S3 批处理任务。

无论您的目标是:

  • 在跨区域切换中重建必要的目录和表级数据
  • 基于动态条件选择性复制对象
  • 快速恢复归档对象以重启 EMR 作业

S3 Batch Operations 结合 manifest generator 都将成为最直接、最高效、最具有操作确定性的方式,支撑跨区域灾备体系的快速恢复能力。

容灾背景

这是一个专为 EMR 跨区域容灾场景 设计的两阶段数据恢复策略,在 EMR 跨区域容灾架构中,生产数据被复制到灾备区域的 S3 Glacier 存储中以降低成本。当需要进行容灾切换或数据恢复时,需要两阶段恢复流程。

第一阶段:发起恢复请求

  • 根据业务需要,精确筛选特定的数据表前缀(如 dwd_table01/…dwd_table08/…)
  • 在亿级归档数据文件中,过滤筛选所需的归档文件,恢复 Glacier 对象
  • 由于文件规模极为庞大,所以尽可能避免全量恢复,只恢复 EMR 作业实际需要的数据集

第二阶段:变更存储级别

  • 将恢复的对象批量复制为标准存储类
  • 确保 EMR 集群可以高性能访问这些数据
  • 为后续的数据处理作业提供最佳性能和最优成本

串行处理模式 vs 并行托管模式

方式一:串行处理模式

  • 执行方式:逐个对象串行处理
  • 资源消耗:依赖本地计算资源和网络带宽
  • 扩展性:受限于单机处理能力
  • 容错性:单点故障影响整个流程
  • 监控能力:缺乏统一的进度跟踪和错误处理
  • 时间复杂度:O(n) 线性增长,处理时间随对象数量成正比

方式二:并行托管模式

  • 执行方式:AWS托管的分布式并行处理
  • 资源消耗:利用AWS云端资源,无本地资源限制
  • 扩展性:自动扩展,可处理数十亿对象
  • 容错性:内置重试机制和错误恢复
  • 监控能力:提供详细的作业报告和进度跟踪
  • 时间复杂度:接近O(1),通过并行处理大幅缩短总时间

关键优势对比

从灾难恢复的角度来看,方式二的优势尤为明显:

  1. 速度优势:方式一处理亿级对象可能需要数天,方式二通过并行处理可在数小时内完成
  2. 可靠性优势:方式一任何环节出错都可能导致整个流程重启,方式二具备自动重试能力
  3. 运维优势:方式一需要持续监控脚本执行状态,方式二提供AWS控制台统一监控
  4. 成本优势:方式一占用本地资源且效率低下,方式二无需本地资源且效率极高

在跨区域灾难恢复场景中,方式二的批量并行托管模式正是实现”最快速有效恢复”的核心技术基础,它将传统的线性处理转变为分布式并行处理,从根本上解决了大规模数据恢复的时效性挑战。

操作过程

方式一:串行处理模式

第一阶段:发起恢复请求

  • 列出指定 prefix 下所有对象
  • 用 query 过滤出 glacier 存储类别的 key
  • 用 jq 拼装成 restore-object 的 key 参数格式
  • xargs 逐行执行 restore-object
#!/bin/bash

BUCKET="warehouse"
PREFIX="data/dwd_table01"

# 列出 Glacier 存储类型的对象并恢复
aws s3api list-objects \
  --bucket "$BUCKET" \
  --prefix "$PREFIX" \
  --output json \
  --query 'Contents[?StorageClass==GLACIER].[Key]' \
| jq -r '.[] | "--key '\''" + .[0] + "'\''" ' \
| xargs -L1 aws s3api restore-object \
  --restore-request Days=7 \
  --bucket "$BUCKET"
  • 这是标准的 Glacier 恢复流程
  • S3 会在后台启动恢复任务,把数据从Glacier 层拉到 S3 的临时可访问区域
  • 通常需要 3–5 小时(Expedited 的话几分钟)

第二阶段:变更存储级别

  • 还是列出 glacier 文件
  • 用 jq 生成 aws s3 cp 命令
  • 通过self-copy,改变 storage-class
#!/bin/bash

BUCKET="warehouse"
PREFIX="data/dwd_table01"

# 列出 Glacier 对象并修改存储类型为 STANDARD
aws s3api list-objects \
--bucket "$BUCKET" \
--prefix "$PREFIX" \
--output json \
--query 'Contents[?StorageClass==GLACIER].[Key]' \
| jq -r —arg bucket "$BUCKET" '.[] | "aws s3 cp —storage-class STANDARD —metadata-directive REPLACE s3://\($bucket)/" + .[0] + " s3://\($bucket)/" + .[0] + ""' \
| bash
  • 把 Glacier 恢复后的临时可读对象复制成 Standard
  • 最终对象变成 STANDARD
  • Glacier 版本依然保留(如果未开启版本控制则被覆盖)

方式二:并行托管模式

第一阶段:发起恢复请求

  • 操作类型S3InitiateRestoreObject – 启动 Glacier 对象恢复
  • 恢复参数
    • 恢复后可访问 7 天 (ExpirationInDays: 7)
    • 使用标准恢复层级 (GlacierJobTier: STANDARD)
  • 目标:将 Glacier 中的冷数据临时恢复到可访问状态
#!/bin/bash

ACCOUNT_ID="[your account id]"
ROLE_NAME="[your role]"

PREFIXES=(
    "data/dwd_table01/"
    "data/dwd_table02/"
    "data/dwd_table03/"
    "data/dwd_table04/"
    "data/dwd_table05/"
    "data/dwd_table06/"
    "data/dwd_table07/"
    "data/dwd_table08/"
    # ...... 其他前缀
)

for p in "${PREFIXES[@]}"; do
    echo "创建 Job,前缀:$p"

    aws s3control create-job \
        --account-id $ACCOUNT_ID \
        --role-arn "arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME" \
        --priority 10 \
        --operation '{
            "S3InitiateRestoreObject": {
                "ExpirationInDays": 7,
                "GlacierJobTier": "STANDARD"
            }
        }' \
        --manifest-generator "{
            \"S3JobManifestGenerator\": {
                \"SourceBucket\": \"arn:aws:s3:::warehouse\",
                \"Filter\": {
                    \"KeyNameConstraint\": {
                        \"MatchAnyPrefix\": [\"$p\"]
                    },
                    \"MatchAnyStorageClass\": [\"GLACIER\"]
                },
                \"EnableManifestOutput\": false
            }
        }" \
        --report "{
            \"Bucket\": \"arn:aws:s3:::report\",
            \"Format\": \"Report_CSV_20180820\",
            \"Enabled\": true,
            \"Prefix\": \"batch_restore_${p//\//_}\",
            \"ReportScope\": \"AllTasks\",
            \"ExpectedBucketOwner\": \"$ACCOUNT_ID\"
        }" \
        --description "batch-restore-$p" \
        --no-confirmation-required

done

第二阶段:变更存储级别

  • 操作类型S3PutObjectCopy – 复制对象
  • 目标:将对象复制到同一个桶 (TargetResource: arn:aws:s3:::warehouse)
  • 目的:通常用于改变存储类,将 Glacier 对象复制为标准存储类
#!/bin/bash

ACCOUNT_ID="[your account id]"
ROLE_NAME="[your role]"

PREFIXES=(
    "data/dwd_table01/"
    "data/dwd_table02/"
    "data/dwd_table03/"
    "data/dwd_table04/"
    "data/dwd_table05/"
    "data/dwd_table06/"
    "data/dwd_table07/"
    "data/dwd_table08/"
    # ...... 其他前缀
)

for p in "${PREFIXES[@]}"; do
    echo "创建 Job,前缀:$p"

    aws s3control create-job \
        --account-id "$ACCOUNT_ID" \
        --role-arn "arn:aws:iam::${ACCOUNT_ID}:role/${ROLE_NAME}" \
        --priority 10 \
        --operation '{
            "S3PutObjectCopy": {
                "TargetResource": "arn:aws:s3:::warehouse"
            }
        }' \
        --manifest-generator '{
            "S3JobManifestGenerator": {
                "SourceBucket": "arn:aws:s3:::warehouse",
                "Filter": {
                    "KeyNameConstraint": {
                        "MatchAnyPrefix": ["'"$p"'"]
                    },
                    "MatchAnyStorageClass": ["GLACIER"]
                },
                "EnableManifestOutput": false
            }
        }' \
        --report '{
            "Bucket": "arn:aws:s3:::report",
            "Format": "Report_CSV_20180820",
            "Enabled": true,
            "Prefix": "batch_restore_'"${p//\//_}"'",
            "ReportScope": "AllTasks",
            "ExpectedBucketOwner": "'"$ACCOUNT_ID"'"
        }' \
        --description "batch-restore-$p" \
        --no-confirmation-required
done

对比分析

归档数据恢复方式二之所以明显优于方式一,是因为它利用了 AWS 原生的 S3 Batch Operations + Manifest Generator,可以做到,更快、更稳定、更自动、可审计、适合亿级对象,性能和可靠性上完全碾压方式一。方式一只有在小规模、临时性恢复时才可用。

对比项 方式一:list+restore+cp 方式二:S3 Batch Restore 优势归属
1 适用规模 ❌ 小规模(上万开始就很痛苦) ✅ 超大规模亿级对象 方式二
2 清单生成方式 手动 list-objects(会失败、超时) 自动 Manifest Generator(强大稳定) 方式二
3 恢复操作 restore-object 逐条执行 S3InitiateRestoreObject 批处理 方式二
4 监控与审计 没有,靠自己加日志 Batch Job 自动生成报告、审计 方式二
5 错误重试能力 脆弱,靠bash和脚本 S3 Batch 自动重试、保证一致性 方式二
6 性能 极慢(xargs/循环)压力大 分布式并行处理(AWS底层执行) 方式二
7 准确性 list-objects 容易漏文件、分页复杂 Manifest Generator 完全准确 方式二
8 稳定性 大 prefix 会导致 CLI/OS 直接挂掉 AWS 内部分布式执行,非常稳 方式二
9 自动发现 Glacier 文件 需要使用本机查询后过滤 使用 MatchAnyStorageClass 由 AWS 服务端过滤 方式二
10 成本 人工成本高,资源消耗极大 自动化节省大量时间 方式二
11 可并行多个 Prefix 需要自己控制并发 本身可以多个 Job 并行 方式二
12 提升存储等级 需要你手动 cp、批量处理 可用另一个 Batch Job 自动完成 方式二

深入探讨

① 方式一依赖 list-objects,非常脆弱且不可靠

方式一第一步是:

aws s3api list-objects

问题:

  • list-objects 默认只列 1000 个(需要分页 next-token)
  • 超大 prefix(几亿文件)CLI 会直接卡死或 OOM
  • Glacier 文件数量大时 jq + xargs 的性能会极差
  • 你需要负责:
    • 分页
    • 错误重试
    • 超时处理
    • 文件过滤
    • 网络抖动

而方式二使用 Manifest Generator,由 AWS 服务端进行扫描、过滤、构造清单

  • 不占用你本机任何内存
  • 不需要分页
  • 不需要自己过滤 StorageClass
  • 完全不会 OOM
  • AWS 内部扫描速度是本地 CLI 至少 几十倍以上

这一个点就已经让方式二绝对碾压方式一。

② 方式一每个对象执行一次 restore-object,非常低效

方式一操作逻辑:

对于每一个对象:
   restore-object

几亿对象会产生几亿个 API 调用,CLI 速度极慢,还容易失败。

方式二 S3 Batch Operations 内部是分布式执行,自动并发

  • 你只需要提交一个 Job
  • AWS 内部自动用大规模分布式 worker 执行恢复请求
  • 吞吐量完全不同级别

③ 方式二能够自动重试、容错,而方式一完全靠人工处理错误

方式一如果恢复某个对象失败,你需要:

  • 手动重新运行
  • 或自己写重试逻辑

方式二:

  • Job 内置自动重试
  • Job 状态自动统计成功/失败
  • 最终会生成错误报告
  • 保证数据不会漏,不需要人工干预

企业级恢复必须要这种“可审计性”,方式一完全不具备。

④ 方式二的性能是方式一的几十倍甚至上百倍

方式二内部是 AWS 的分布式执行架构,可以:

  • 数万并行(server-side distributed execution)
  • 不受你 EC2 的 CPU/内存限制
  • 不受 CLI 的性能限制
  • 不受网络带宽限制

方式一是单机 CLI:

  • 性能差
  • 网络慢
  • 容易中断
  • 一次只能处理非常有限数量

⑤ 方式二不会对本机造成任何压力

方式一会:

  • 扫描对象列表
  • 在本机 jq 处理大型 JSON
  • xargs 并发调用 aws cli

如果对象数量是亿级,你的服务器:

  • 内存暴涨
  • CPU 爆炸
  • CLI 卡死
  • 直接 OOM

方式二全部在 AWS 内部执行,客户端只发一个 API 调用。

⑥ 方式二天然支持 Prefix 分片 + 多 Job 并行,更适合大规模恢复

方式二代码里:

PREFIXES=(table01...table08...)for p in PREFIXES: create job

这意味着:

  • 每个前缀生成一个独立 Job
  • Job 可以并行恢复
  • 互不影响
  • AWS 会自动扩容执行

方式一必须:

  • 手工控制并行
  • 控制带宽
  • 避免 API 速率限制
  • 避免机器崩溃

不可控,尤其是上亿文件。

⑦ 方式二可生成恢复报告,有审计能力

批处理 job 会生成:

成功文件列表
失败文件列表
失败原因(AccessDenied、InvalidObjectState、NotFound)
总处理数
每个对象的恢复状态

方式一没有任何审计能力。

生产环境必须有审计。

⑧ 方式二减少人为操作错误

方式一的命令链很复杂:

  • list-objects
  • jq 过滤
  • xargs
  • restore-object
  • 再 cp self-copy

任何一步都有可能出错:

  • 错误恢复
  • 漏对象
  • 生成损坏的数据
  • data lake 数据不一致

方式二:

  • RESTORE 是原生服务级全托管执行
  • 由 AWS 保证一致性

可靠性显著更高。

结语

S3 Batch Operations 的 manifest generator 为 EMR 跨区域应急备份恢复场景提供了有效的解决方案。在传统的 EMR 容灾架构中,生产数据被复制到灾备区域的 S3 Glacier 存储以降低成本,但当灾难发生需要紧急切换时,数据恢复的速度往往成为业务连续性的重要考量因素。
通过 manifest generator,您可以在灾难发生的第一时间,无需等待 Inventory 报告或编写复杂脚本,即可对特定的数据表前缀执行即时、精准的批量恢复操作。这种能力对于 EMR 跨区域容灾场景具有重要意义,它将传统方式需要数天才能完成的亿级归档文件恢复,压缩至数小时内完成。
本文展示的两阶段恢复策略,从 Glacier 恢复到标准存储类的完整流程,充分体现了 manifest generator 如何将复杂的 EMR 容灾恢复工作流转化为简化的、按需执行的自动化操作。无论是精确筛选特定数据表、批量恢复归档对象,还是变更存储级别以确保 EMR 集群的高性能访问,整个流程都可以在灾难响应的关键时刻立即启动。
在 EMR 跨区域容灾的实际场景中,恢复速度是业务连续性的关键要素。S3 Batch Operations 的 manifest generator 不仅提供了技术上的改进,更为企业的业务连续性提供了可靠支撑。您可以将这一能力整合到 EMR 容灾运营工作流中,确保在面对突发情况时,都能快速恢复关键数据,让 EMR 集群重新投入生产,有效减少业务中断时间和影响。

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者

张羽

亚马逊云科技解决方案架构师

唐亮

亚马逊云科技技术客户经理,专注大数据及数据分析领域十余年,曾就职于联想、IBM等公司。

AWS 架构师中心: 云端创新的引领者

探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用