AWS 大数据深度剖析(第四部分):Glue Catalog、Athena 与 Lake Formation

AWS Glue Data Catalog 如何充当数据湖的中央目录,以及 Athena 如何用无服务器 SQL 查询 S3 上的 Parquet 与 Iceberg 表。

zhuermu··13 分钟
big-dataawsglue-catalogathenalake-formationmetadataserverless-sql

数据已经落到了 S3 上——Athena、Spark、SageMaker 怎么知道「这是一张表,它有这些列」?答案是:Glue Data Catalog

表注册好之后,谁来执行 SQL?答案是:Athena(无服务器)/ EMR Spark(重负载)/ Redshift(高并发 BI)。

谁来控制「哪些字段能被哪些人看到」?答案是:Lake Formation


为什么你需要一个中央元数据目录

没有 Catalog 会发生什么?下面是一个常见的灾难场景:

团队 A:在 Athena 中创建了一张按 dt 分区的 `events` 表
团队 B:用 EMR Spark 以自己的 schema 读取 events,发现某个列的类型对不上
团队 C:用 SageMaker 做训练,CSV 模式 + 硬编码列名

三个团队,三套 schema,没人知道哪一套才是对的——数据治理就此崩溃。

Glue Data Catalog 就是唯一可信来源(single source of truth):每个引擎都从同一个地方读取表定义——一个元数据存储统御一切。

Glue Catalog 架构


AWS Glue Data Catalog 详解

它是什么——以及它不是什么

它是:一个只存储元数据的服务(即 Metastore)。 它不是:数据库(它不存业务数据),也不是查询引擎(它不跑 SQL)。

打个比方:它就像图书馆的卡片目录——它告诉你「《活着》这本书在 3 楼 B 区第 5 排第 12 个位置」。书本身在 3 楼。

三级层次结构

Glue Data Catalog                ← 每个 AWS 账户一个(全局)
└── Database                     ← 命名空间(类似于一个「schema」)
    └── Table                    ← 单张表
        ├── Schema(列名、类型)
        ├── Location (s3://...)  ← 数据在 S3 中的位置
        ├── Partitions (dt=...)  ← 分区定义
        ├── Storage format(Parquet / Iceberg / CSV)
        └── 其他属性

数据进入 Catalog 的四种方式

方式最适用场景自动化程度
Zero-ETL / 基于 DMS 的 Zero-ETLAurora / RDS MySQL CDC全自动
Glue Crawler已有的 S3 数据;自动推断 schema 并注册
Glue ETL Job(写入时注册)Spark 写入新分区并自动注册
手动 CREATE TABLE / Terraform完全受控的生产环境低——但最稳定

生产最佳实践:用手动 / Terraform 来定义 ODS / DWD / DWS / ADS 的表 schema(可控)。Crawler 只用于探索性数据。

什么是 Glue Crawler?

Crawler 是一个「扫描 S3 并自动建表」的工具:

  • 你给它一个 S3 路径
  • 它扫描几个文件,推断列类型和分区
  • 它在 Catalog 中自动注册这张表

优点:方便。 缺点:推断出的类型可能出错(例如把 string 推断成 int),分区检测也可能不稳定。在生产环境中,务必审查 Crawler 的输出。

Iceberg 表是特殊的

Iceberg 表不会把 Parquet 文件路径注册到 Catalog 中,而是注册一个指向 Iceberg metadata.json 文件的指针

ods_user 表在 Catalog 中的条目:
  TBLPROPERTIES:
    table_type = 'ICEBERG'
    metadata_location = 's3://.../ods_user/metadata/v123.json'

每次写入时:Iceberg 会写出一个新的 metadata.json,然后 Catalog 原子性地将 metadata_location 指针更新到新版本。

关键洞察:每个读取 Iceberg 表的引擎,都会先从 Catalog 获取当前的元数据指针,然后解析元数据以得到一份精确的文件清单(manifest)。这正是数据湖中实现 ACID 事务的方式。

跨账户与跨区域

  • 同账户、同 Region:直接共享
  • 跨账户:通过 Lake Formation 资源共享(Resource Sharing) 授权访问
  • 跨 Region:使用 Glue 跨区域 Catalog(Cross-Region Catalog)(2024 年起可用)

定价

非常便宜:

  • 前 100 万个对象(表 + 分区):免费
  • 之后:每月每 100 万个对象 1 美元
  • API 请求:每月前 100 万次免费,之后每 100 万次 1 美元

在实践中,对于任何真实的数据仓库,这项成本都可以忽略不计。

官方文档


Amazon Athena:无服务器 SQL 查询

什么是 Athena?

一句话概括:给它一张已在 Glue Catalog 中注册的表,再加上一条 SQL 查询,它就会执行查询并返回结果。无服务器,按扫描量计费。

其底层引擎是 Trino(前身为 Presto,最初由 Facebook 开源的分布式 SQL 引擎),由 AWS 托管并优化。

一次查询在内部是如何执行的

Athena 执行流程

四个步骤:

  1. 解析 SQL——生成逻辑计划
  2. 查询 Glue Catalog——获取表定义、分区列表、文件位置
  3. 分区裁剪 + 谓词下推——精确确定需要读取哪些文件和哪些列
  4. 并行的 Trino worker 读取 S3——聚合结果——将输出写入 S3——返回

整个过程对你是透明的:你提交 SQL,拿回结果。AWS 把 Trino 集群完全隐藏在幕后。

计费模型

按扫描的字节数计费(在 us-east-1 约为 $5/TB)。理解这一点是控制成本的关键。

「扫描的字节数」指的是从 S3 读取的 Parquet 数据,而不是结果集的大小:

-- 假设 ods_event 总共 1 TB
SELECT COUNT(*) FROM ods_event;                          -- scans 1 TB → $5
SELECT COUNT(*) FROM ods_event WHERE dt='2026-05-10';    -- scans 30 GB (one day) → $0.15
SELECT user_id  FROM ods_event WHERE dt='2026-05-10';    -- scans 3 GB (one day + one column) → $0.015

头两个数量级的成本节省来自数据布局——这正是为什么 Parquet + 分区 + Iceberg 是一套必备组合。

性能优化技巧(按收益排序)

#技巧节省
1将 CSV/JSON 转为 Parquet70-90%
2按 dt 分区并使用 WHERE dt=’…‘90%+
3谓词下推(利用 Parquet 列统计信息 / Iceberg)50-90%
4合理设置文件大小(128-512 MB)减少约 30% 的元数据开销
5使用 Iceberg 而非 Hive 表更精确的文件级跳过
6LIMIT + 列裁剪(用 SELECT col1, col2 而非 SELECT *50-90%
7在 Workgroup 中设置最大扫描量限制防止失控查询

Workgroup(工作组)

Workgroup 是 Athena 内部的「配置容器」,它把以下内容打包在一起:

设置项用途
引擎版本v2 / v3(完整支持 Iceberg + 更好的性能需要 v3)
结果位置查询结果写入哪个 S3 桶
加密结果的加密配置
成本限制每条查询的最大扫描量 / 每个 Workgroup 的最大扫描量
数据用量控制阈值告警
标签(Tags)用于成本分摊

生产最佳实践:每个团队或业务单元一个 Workgroup,从而实现:

  • 账单拆分(CloudWatch 按 Workgroup 出报表)
  • 成本治理(设置上限以防止昂贵的失控查询)
  • 引擎隔离(某些团队仍在用 v2,而不影响其他团队)

Provisioned Capacity(预置容量,2023 年起)

普通的 Athena 是无服务器的,但有时业务需要严格的 SLA(例如一个必须在 5 秒内返回的 BI 看板——按需模式偶尔会排队)。

Athena Provisioned Capacity:预先购买专用的计算单元(DPU),以保证稳定的延迟。

  • 最少 24 个 DPU(约 $20/小时),按小时计费
  • 适用于对 SLA 有严格要求的工作负载;常规分析并不需要它

Athena 也能写:CTAS 与 INSERT INTO

Athena 并非只读——它也可以写入数据:

-- CREATE TABLE AS SELECT
CREATE TABLE dwd_user_action
WITH (
  format = 'PARQUET',
  partitioned_by = ARRAY['dt'],
  location = 's3://my-bucket/warehouse/dwd/user_action/'
) AS
SELECT * FROM ods_event WHERE event_type = 'click';

-- Insert into a new partition
INSERT INTO dwd_user_action
SELECT * FROM ods_event WHERE dt = '2026-05-10';

-- Iceberg table UPDATE / DELETE / MERGE (v3 supports this)
MERGE INTO dwd_user_action t USING staging s
ON t.event_id = s.event_id ...

这就是为什么轻量级的 ODS / DWD / DWS / ADS 分层转换最好交给 Athena CTAS(最便宜的选项),而重型处理则交给 EMR / Glue Spark。

官方文档


Athena 与其他查询引擎的对比

Athena vs. Redshift

AthenaRedshift
架构无服务器,存算分离(数据在 S3)传统 MPP,存算耦合
数据位置S3(属于你)Redshift 自己的专用存储
计费按扫描字节数按节点 / 按小时
并发默认 25(可调)50+(配合 Concurrency Scaling)
性能中(典型 4-30 秒)高(亚秒级到几秒)
最适用于数据湖临时查询 / ETL / ML 数据提取高并发的 BI 看板

如何选择:我们的架构走的是数据湖路线,以 Athena 作为主引擎。如果你还需要高并发 BI(例如 100 名分析师同时刷新看板),可以在上层叠加 Redshift Spectrum(用 Redshift 的引擎查询 S3 外部表),实现「热数据在 Redshift,冷数据在 S3」的策略。

Athena vs. EMR Spark

AthenaEMR Spark
编程方式仅 SQLSQL + Python + Scala + UDF
复杂度中到高
最适用于简单的转换 / 聚合 / 任何 SQL 能表达的操作重型 ETL / ML / 复杂逻辑
性能Trino 在中小数据集上很快Spark 在 TB 级以上数据集上更稳定

实践中:Athena CTAS 处理简单的 SQL 作业;EMR Serverless 处理复杂的 Spark 作业;两者共享同一个 Glue Catalog。


Lake Formation:数据治理与细粒度权限

为什么你需要它

Catalog 解决了「这是什么表」的问题,但**「谁能看到哪些列、哪些行」** 需要一个专门的权限层。

举例来说:

  • ML 团队需要访问 ads_user_features,但绝不能看到 phone 或 id_card 列
  • BI 分析师只能看到自己所在区域的数据
  • 审计人员可以读取所有数据,但不能修改任何内容

传统数据仓库(如 Redshift)有自己的权限系统。但在数据分散于 S3 的数据湖中,你要如何管理访问权限?答案是 Lake Formation

什么是 Lake Formation?

Lake Formation 是 AWS 构建在 Glue Catalog 之上的细粒度权限管理层:

  • 行级安全(Row-Level Security)
  • 列级安全(Column-Level Security)
  • 数据脱敏 / 基于标签的访问控制(TBAC)
  • 跨账户数据共享

工作原理

传统模型(仅 IAM):
  IAM Role → S3 bucket policy → 这个 role 能读取 s3://bucket/path 吗?

Lake Formation 模型:
  IAM Role
    → Glue Catalog(Table 概念)
      → Lake Formation 检查:这个 Role 对 ods_user 的特定列是否有 SELECT 权限?
        → 拒绝某些列 / 行,或整体拒绝

示例:列级权限

Lake Formation 的列级授权不是标准 ANSI SQL——它通过三种方式进行配置:

方式一:LF 控制台 / API(生产环境推荐)

在 Lake Formation 控制台中:Data permissions,Grant。选择 IAM Role + 表 + 勾选可见的列(include columns)或排除敏感列(exclude columns)。等价的 CLI:

aws lakeformation grant-permissions \
  --principal DataLakePrincipalIdentifier=arn:aws:iam::123:role/data-science-role \
  --permissions SELECT \
  --resource '{
    "TableWithColumns": {
      "DatabaseName": "poc_social_layla",
      "Name": "ads_user_features",
      "ColumnNames": ["user_id","age","city","tags"]
    }
  }'

方式二:Athena 的 LF 风格 GRANT(引擎 v3 + 由 LF 管理的表)

GRANT SELECT (user_id, age, city, tags)
ON poc_social_layla.ads_user_features
TO PRINCIPAL 'arn:aws:iam::123:role/data-science-role';

注意 TO PRINCIPAL '<完整 ARN>'——这不是 PostgreSQL/Redshift 风格的 TO ROLE 'name'

效果

SELECT * FROM ads_user_features;                    -- Denied (includes phone/id_card)
SELECT user_id, age, tags FROM ads_user_features;   -- OK

方式三:LF 基于标签的访问控制(LF-TBAC):给表/列打标签(例如 pii=true),然后按标签授予权限。对大型组织而言更具可扩展性。

常见坑

Lake Formation 的配置很复杂。常见的痛点:

  • 权限叠加在 IAM 之上——调试时需要检查两层
  • 由 Glue Crawler 自动创建的表可能不会继承 LF 权限
  • 跨账户共享需要 Resource Links 才能生效

实用建议:在 POC 阶段,跳过 Lake Formation(使用粗粒度的 IAM)。等到进入生产环境时再启用它。

官方文档Lake Formation


元数据 + 查询的全景图

┌─────────────────────────────────────────────────────┐
│              S3 物理数据层                            │
│   warehouse/ods/event/dt=2026-05-10/*.parquet       │
└──────────────────────┬──────────────────────────────┘

                       │ 文件级访问

┌──────────────────────┴──────────────────────────────┐
│            Glue Data Catalog(元数据)               │
│   poc_social_layla.ods_event                        │
│     schema、分区、location → s3://...               │
└──────────────────────┬──────────────────────────────┘

                       │ 获取表定义

┌──────────────────────┴──────────────────────────────┐
│       Lake Formation(权限层,可选)                 │
│   针对每个 IAM Role:哪些列 / 行可见                │
└──────────────────────┬──────────────────────────────┘

        ┌──────────────┼─────────────┬─────────────┐
        │              │             │             │
   Athena (SQL)    EMR Spark    SageMaker    Redshift Spectrum

本章小结

概念一句话总结
Glue Data Catalog数据湖的中央表元数据存储,被所有引擎共享
Glue Crawler扫描 S3 并自动建表(生产环境需谨慎使用)
Iceberg + CatalogCatalog 存储的是指向 Iceberg metadata.json 的指针
Athena无服务器 SQL 引擎,由 Trino 驱动,按扫描字节数计费
WorkgroupAthena 的配置容器,用于成本治理和团队隔离
Lake Formation列级 / 行级权限管理——在 IAM 之上的细粒度访问控制

参考资料

  1. AWS Glue Developer Guide — AWS Documentation
  2. Trino documentation — Trino
  3. Amazon Athena User Guide — AWS Documentation