AWS Glue + EMR 大数据处理实战:从零搭建 ETL 数据管道(2026最新教程)
Meta Description: AWS Glue 和 EMR 大数据 ETL 实战教程,手把手教你用 AWS 搭建数据处理管道。
- 前言
- AWS Glue vs EMR:两大 ETL 方案核心区别
- AWS Glue 实战:用 Crawler 自动发现 S3 数据
- Amazon EMR 实战:Spark 集群搭建与作业提交
- Glue 与 EMR 价格对比:谁更省钱?
- 实战场景:搭建一个完整的 S3 → ETL → 数据仓库管道
- AWS Glue Studio 可视化 ETL:不会写代码也能用
Meta Description: AWS Glue 和 EMR 大数据 ETL 实战教程,手把手教你用 AWS 搭建数据处理管道。包含 Glue vs EMR 选型对比、Glue Crawler 自动发现 Schema、Spark 作业调试、定价详解与省钱技巧。
关键词: AWS Glue、AWS EMR、ETL 数据管道、大数据处理、Spark on AWS、数据湖
前言
很多团队在搭建数据平台时面临一个经典问题:数据散落在 S3、RDS、DynamoDB 等多个源头,需要定期清洗、转换、加载到数据仓库或数据湖中。AWS 提供了两大核心工具来解决这个问题:AWS Glue(无服务器 ETL)和 Amazon EMR(托管大数据集群)。两者都能跑 Spark 作业,但定位和适用场景完全不同。
决策口诀: 小中型 ETL 用 Glue(免运维、按秒计费),大规模批处理或已有 Hadoop 生态用 EMR(灵活、便宜)。
一、AWS Glue vs EMR:两大 ETL 方案核心区别
选对工具是成功的一半。Glue 和 EMR 的区别不仅是"托管程度",更在于数据规模、团队技能和运维预算的综合考量。
| 对比维度 | AWS Glue | Amazon EMR |
|---|---|---|
| 架构模式 | 无服务器(Serverless) | 托管集群(需选实例类型) |
| 是否需要管理服务器 | 完全不需要 | 需要管理 Master/Core/Task 节点 |
| 支持的计算引擎 | Spark、Python Shell、Ray | Spark、Hadoop、Hive、Presto、Flink |
| 最大运行时长 | 48 小时(可续) | 无限制(集群存续期间) |
| 按需起停 | 自动,闲置不计费 | 需手动或用调度器控制 |
| 定价模型 | vCPU·小时 + 内存·GB·小时 | EC2 实例费 + EMR 管理费 |
| 适合数据规模 | GB 到低 TB 级 | TB 到 PB 级 |
| 学习曲线 | 低(可视化 + Python/Scala) | 中高(需 Spark/Hadoop 经验) |
| 数据目录 | 内置 AWS Glue Data Catalog | 需自建 Hive Metastore 或用 Glue |
| 可视化 ETL 编辑器 | 有(Glue Studio) | 无(纯代码) |
一句话总结: 如果你的数据在 TB 级以下、团队不想运维集群,选 Glue;如果你需要 PB 级处理、多引擎混用、或已有 Hadoop 作业要迁移,选 EMR。
二、AWS Glue 实战:用 Crawler 自动发现 S3 数据
Glue 最强大的功能之一是 Crawler——它能自动扫描 S3 存储桶,发现数据格式(CSV、JSON、Parquet、Avro),推断 Schema,然后在 Data Catalog 中创建表。省去了手动定义 Schema 的繁琐工作。
2.1 前置准备
在开始之前,确保你已:
- 注册了 AWS 国际版账号(参见 免费套餐注册教程)
- 安装了 AWS CLI 并配置了 Access Key
- 在 S3 中准备了示例数据(CSV 或 JSON 格式均可)
2.2 创建 Glue 数据库和 Crawler
通过 AWS CLI 创建一个 Glue 数据库,用于存放 Crawler 发现的表元数据:
aws glue create-database --database-input '{
"Name": "my_etl_database",
"Description": "ETL pipeline demo database"
}'
接下来创建 IAM 角色,授予 Glue 访问 S3 和 Data Catalog 的权限:
aws iam create-role --role-name GlueServiceRole --assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{"Effect": "Allow", "Principal": {"Service": "glue.amazonaws.com"}, "Action": "sts:AssumeRole"}]
}'
附加托管策略:
aws iam attach-role-policy --role-name GlueServiceRole --policy-arn arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole
2.3 运行 Crawler 扫描 S3 数据
创建 Crawler 并指定 S3 数据源:
aws glue create-crawler --name my-s3-crawler --role GlueServiceRole \
--database-name my_etl_database \
--targets '{"S3Targets": [{"Path": "s3://my-data-bucket/raw/"}]}' \
--schema-change-policy '{"UpdateBehavior": "UPDATE_IN_DATABASE", "DeleteBehavior": "LOG"}'
运行 Crawler:
aws glue start-crawler --name my-s3-crawler
Crawler 运行完成后,你可以在 Glue 控制台的 Data Catalog → 数据库 → 表 中看到自动创建的表,包含列名、数据类型等 Schema 信息。
2.4 创建 ETL 作业
Crawler 发现数据后,创建一个 Spark ETL 作业来清洗和转换数据:
aws glue create-job --name my-etl-job --role GlueServiceRole \
--command '{
"Name": "glueetl",
"ScriptLocation": "s3://my-etl-scripts/transform.py",
"PythonVersion": "3"
}' \
--default-arguments '{
"--job-language": "python",
"--TempDir": "s3://my-etl-temp/",
"--output_path": "s3://my-data-bucket/processed/"
}'
Python ETL 脚本示例(transform.py):
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from awsglue.context import GlueContext
from pyspark.context import SparkContext
// 初始化 Glue 上下文
args = getResolvedOptions(sys.argv, ['JOB_NAME', 'output_path'])
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
// 从 Data Catalog 读取表
dynamic_frame = glueContext.create_dynamic_frame.from_catalog(
database="my_etl_database",
table_name="raw_data"
)
// 转换:过滤空值、添加处理时间戳
df = dynamic_frame.toDF()
df_clean = df.filter(df["id"].isNotNull())
df_clean = df_clean.withColumn("processed_at", current_timestamp())
// 写入 Parquet 格式(列式存储,查询更快)
df_clean.write.mode("overwrite").parquet(args['output_path'])
print("ETL job completed successfully")
运行作业:
aws glue start-job-run --job-name my-etl-job
免费套餐提示: Glue 每月提供 100 万 AWS Glue Data Catalog 存储对象免费额度和 100 万次请求免费额度。Crawler 运行时间和 ETL 作业 vCPU·小时按量计费,小规模测试每月通常不超过 $5。
三、Amazon EMR 实战:Spark 集群搭建与作业提交
当你需要运行大规模 Spark 作业、需要更灵活的集群配置,或者有现成的 Hadoop 作业要迁移时,EMR 是更好的选择。EMR 的核心优势在于:你完全控制集群的实例类型、数量和配置,同时 AWS 托管了集群的部署、监控和补丁管理。
3.1 创建 EMR 集群
使用 AWS CLI 创建一个 Spark 集群:
aws emr create-cluster --name my-spark-cluster \
--release-label emr-7.0.0 \
--applications Name=Spark \
--instance-groups '[
{
"InstanceGroupType": "MASTER",
"InstanceType": "m5.xlarge",
"InstanceCount": 1
},
{
"InstanceGroupType": "CORE",
"InstanceType": "m5.2xlarge",
"InstanceCount": 2
}
]' \
--service-role EMR_DefaultRole \
--ec2-attributes InstanceProfile=EMR_EC2_DefaultRole
3.2 提交 Spark 作业
集群启动后,通过 SSH 连接到 Master 节点提交作业:
aws emr ssh --cluster-id j-XXXXXXXXX --key-pair-file ~/.ssh/my-key.pem
提交 Spark 作业:
spark-submit \
--master yarn \
--deploy-mode cluster \
s3://my-etl-scripts/transform.py \
--input_path s3://my-data-bucket/raw/ \
--output_path s3://my-data-bucket/processed/
也可以通过 EMR 步骤(Step)功能直接从外部提交,无需 SSH:
aws emr add-steps --cluster-id j-XXXXXXXXX --steps '[
{
"Type": "Spark",
"Name": "My ETL Job",
"ActionOnFailure": "CONTINUE",
"Args": ["--class", "com.example.Main", "s3://my-etl-scripts/job.jar", "--input", "s3://my-data-bucket/raw/"]
}
]'
3.3 EMR 成本控制关键技巧
EMR 的最大开销来自 EC2 实例,控制成本的关键在于 合理选择实例类型和使用 Spot 实例。
aws emr create-cluster --name my-cost-optimized-cluster \
--release-label emr-7.0.0 \
--applications Name=Spark \
--instance-groups '[
{
"InstanceGroupType": "MASTER",
"InstanceType": "m5.xlarge",
"InstanceCount": 1
},
{
"InstanceGroupType": "CORE",
"InstanceType": "m5.xlarge",
"InstanceCount": 3
},
{
"InstanceGroupType": "TASK",
"InstanceType": "m5.xlarge",
"InstanceCount": 5,
"BidPrice": "0.15"
}
]' \
--service-role EMR_DefaultRole \
--ec2-attributes InstanceProfile=EMR_EC2_DefaultRole
省钱要点: Task 节点使用 Spot 实例(BidPrice 为按需价格的 60-70%),Core 节点用按需实例保证稳定性。这种混合模式可以将整体成本降低 40-50%。
四、Glue 与 EMR 价格对比:谁更省钱?
定价模型不同是选型的核心考量。Glue 按秒计费、无闲置成本;EMR 按实例计费但有集群调度优化空间。
Glue 定价(us-east-1,2026 年参考价)
| 资源 | 价格 |
|---|---|
| vCPU·小时 | $0.44 |
| 内存·GB·小时 | $0.044 |
| Data Catalog 存储 | 每月前 100 万个对象免费 |
| Crawler 运行 | 按 vCPU·小时计费 |
Glue 月费估算示例: 每天运行 1 小时,使用 2 vCPU + 4GB 内存的 DPU 配置,月费约 30 × 1 × (0.44 × 2 + 0.044 × 4) ≈ $31.68。
EMR 定价(us-east-1,2026 年参考价)
| 实例类型 | 按需价格(每小时) | Spot 价格(参考) | 月费估算(按需,24h 运行) |
|---|---|---|---|
| m5.xlarge(4vCPU/16GB) | $0.192 | ~$0.06 | ~$138 |
| m5.2xlarge(8vCPU/32GB) | $0.384 | ~$0.12 | ~$277 |
| r5.xlarge(4vCPU/32GB) | $0.252 | ~$0.08 | ~$181 |
| c5.2xlarge(8vCPU/16GB) | $0.34 | ~$0.10 | ~$245 |
EMR 管理费: 每个集群每小时额外收取 $0.52(Master 节点)+ $0.13 per vCPU(Core/Task 节点)。
关键结论:
- 偶发性 ETL(每天 1-2 小时): Glue 更便宜——没有闲置成本,按秒计费
- 全天候运行: EMR + Reserved Instances 或 Savings Plans 更便宜——长期运行分摊后单价低
- 突发大规模处理: EMR + Spot 实例最灵活——可以临时扩展到几十个节点,处理完即销毁
五、实战场景:搭建一个完整的 S3 → ETL → 数据仓库管道
下面是一个完整的数据处理管道架构,从数据采集到最终查询:
场景描述
一家电商公司将每日订单数据(JSON 格式)存放在 S3 中,需要每天清洗、转换后加载到 Amazon Redshift 数据仓库,供 BI 团队查询分析。
架构设计
数据流: S3(原始 JSON)→ Glue Crawler(发现 Schema)→ Glue ETL Job(清洗转换)→ S3(Parquet 格式)→ Glue Crawler(更新 Schema)→ Amazon Redshift Spectrum 或 Redshift COPY 加载
实现步骤
第一步:数据入库 S3
使用 AWS CLI 或 SDK 将订单 JSON 文件上传到 S3:
aws s3 cp orders_2026-09-07.json s3://my-data-lake/raw/orders/
第二步:Glue Crawler 扫描新数据
每天定时触发 Crawler,让 Glue 自动识别新文件的 Schema:
aws glue start-crawler --name orders-crawler
第三步:运行 ETL 转换
ETL 脚本执行数据清洗(去重、类型转换、空值填充)和格式转换(JSON → Parquet):
from awsglue.transforms import *
from awsglue.context import GlueContext
from pyspark.context import SparkContext
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
// 读取原始数据
dyf = glueContext.create_dynamic_frame.from_catalog(
database="ecommerce_db",
table_name="orders_raw"
)
// 清洗:去重 + 过滤无效订单
df = dyf.toDF()
df_clean = df.dropDuplicates(["order_id"]).filter(df["amount"] > 0)
// 添加分区字段
df_final = df_clean.withColumn("dt", lit("2026-09-07"))
// 写入 Parquet
df_final.write.mode("overwrite").partitionBy("dt").parquet("s3://my-data-lake/processed/orders/")
第四步:加载到 Redshift
使用 Redshift 的 COPY 命令从 S3 批量加载:
COPY orders
FROM 's3://my-data-lake/processed/orders/'
IAM_ROLE 'arn:aws:iam::123456789012:role/RedshiftCopyRole'
FORMAT AS PARQUET;
整个管道通过 AWS Step Functions 或 EventBridge 定时调度,每天凌晨自动执行。
六、避坑指南:大数据处理常见问题
6.1 Glue 作业超时
问题: Glue 作业默认超时为 48 小时,大规模数据处理可能超时。
解决:
- 在作业参数中设置
--job-bookmark-option启用增量处理,避免每次全量扫描 - 拆分为多个小作业,使用 Step Functions 编排执行顺序
- 升级到 Glue 4.0(Spark 3.3)获得更好的性能优化
6.2 EMR 集群闲置浪费
问题: 集群启动后如果没有及时提交作业,EC2 实例一直在计费。
解决:
- 使用 EMR 可扩展集群(Auto Scaling),根据负载自动调整节点数
- 使用 EMR 步骤调度功能,作业完成后自动终止集群
- 考虑用 Glue 替代偶发性任务——Glue 无闲置成本
6.3 数据 Schema 漂移
问题: 上游数据格式变化(新增字段、类型变更),导致 ETL 作业失败。
解决:
- Glue Crawler 配置
SchemaChangePolicy为UpdateBehavior: UPDATE_IN_DATABASE - 在 ETL 脚本中使用
resolveChoice()处理 Schema 冲突 - 定期运行 Crawler 更新 Data Catalog
6.4 小文件问题
问题: 大量小文件(几十 KB)导致 Spark 读取效率极低。
解决:
- 在 ETL 输出时使用
coalesce()或repartition()合并文件 - Glue 输出时配置
partitionKeys和groupFiles参数 - 定期运行 Spark 合并脚本,将小文件合并为 128MB-256MB 的文件
七、AWS Glue Studio 可视化 ETL:不会写代码也能用
对于非技术团队,AWS 提供了 Glue Studio——一个可视化 ETL 编辑器,通过拖拽节点就能构建数据管道。
核心功能:
- 可视化画布: 拖拽源节点(S3、RDS、DynamoDB)和转换节点(过滤、聚合、Join),自动生成 Spark 代码
- SQL 编辑器: 直接写 SQL 定义转换逻辑,Glue 自动转为 Spark 作业
- 实时预览: 在发布前预览转换结果,确认数据正确性
- 作业图: 将多个 Glue 作业编排为 DAG(有向无环图),支持分支和条件执行
启用方式:在 AWS Glue 控制台点击 "Studio" → "可视化 ETL" → 创建作业。无需额外费用,按 Glue 标准定价计费。
常见问题(FAQ)
AWS Glue 免费套餐包含什么?
Glue 免费套餐包含:每月 100 万个 Data Catalog 存储对象免费、每月 100 万次请求免费、Crawler 和 ETL 作业按量计费(无免费额度)。新用户前 12 个月可享受部分免费额度。
Glue 和 EMR 可以混用吗?
可以。很多团队用 Glue 管理 Data Catalog(统一数据目录),用 EMR 运行大规模 Spark 作业——EMR 可以直接连接 Glue Data Catalog,读取表元数据。
小团队(1-3 人)应该选哪个?
推荐从 Glue 开始。零运维、按秒计费、内置数据目录,对小团队最友好。等数据规模超过 TB 级或需要多引擎时再考虑 EMR。
EMR 支持哪些 Spark 版本?
EMR 7.x 支持 Spark 3.5,EMR 6.x 支持 Spark 3.3/3.4。建议使用最新版本以获得性能优化和安全修复。
如何监控 ETL 作业的执行状态?
通过 CloudWatch 监控 Glue 作业指标(运行时间、DPU 使用量、错误数),或在 EMR 控制台查看 Spark UI 和 YARN 应用状态。
Glue 数据能直接查询吗?
可以。通过 Amazon Athena 可以直接用 SQL 查询 S3 上的 Glue 表数据,无需加载到数据库。适合临时查询和数据分析场景。
处理 GB 级数据用 Glue 够吗?
足够。Glue 最小配置 2 个 DPU(16GB 内存),处理 GB 级数据通常几分钟完成。按秒计费,小规模任务成本很低。
⚠️ 文中价格为 2026 年参考价,实际费用随区域和官方调价变动,请以 AWS 官网为准。
🚀 需要 AWS 国际版账号?通过 3.chengzicloud.cloud 获取最新注册教程与专属优惠,助你轻松上云。
延伸阅读:
本文由 3.chengzicloud.cloud 提供,点击访问首页了解更多