4. S3数据湖分层设计
在S3上构建数据湖,最容易失败的方式不是选错存储类型,而是把所有数据都堆进同一个前缀下,靠文件名区分来源和状态。分层设计的核心目的,是让每一层承担明确的数据责任:原始区保存不可变的事实,清洗区承载标准化过程,可信区提供经过校验的权威数据,消费区面向具体查询和下游应用做裁剪与聚合。四层之间通过目录前缀、分区键、文件格式和生命周期规则形成一条可追溯、可重跑、可治理的数据链路。
四层目录规划:用前缀表达数据责任
推荐以存储桶为边界,按层建立顶层前缀,再按“来源系统/数据集/分区”组织。一个可落地的目录结构如下:
s3://company-data-lake/
raw/ # 原始区:只追加,不修改
orders/
source=mysql/
dt=2025-03-01/
orders_20250301_001.json.gz
cleaned/ # 清洗区:标准化、去重、类型转换
orders/
dt=2025-03-01/
part-00000.parquet
trusted/ # 可信区:校验通过、口径统一
orders/
dt=2025-03-01/
part-00000.parquet
consumption/ # 消费区:面向主题的聚合与宽表
sales_daily/
dt=2025-03-01/
part-00000.parquet
原始区必须保持不可变:同一批数据重复写入时,用唯一文件名或写入时间戳区分,而不是覆盖旧文件。这样当清洗逻辑出错时,可以回到原始区重跑,而不依赖上游系统重新推送。清洗区和可信区允许按分区覆盖重写,但每次重写应记录批次ID或版本号,便于回溯。消费区则按查询模式组织,例如按天聚合的销售宽表、按用户维度的画像表,避免让BI工具直接扫描可信区的明细。
分区策略:分区键决定扫描成本
S3本身没有索引,分区是减少扫描量的主要手段。分区键应选择查询中高频出现的过滤字段,且基数适中。常见组合是“日期 + 业务维度”,例如 dt=2025-03-01/region=cn-north/。日期分区几乎总是必要的,因为大多数分析都带时间范围;业务维度分区则取决于查询模式,如果经常按地区、渠道、租户过滤,就值得加入。
需要避免两个极端:分区过粗,比如只按年分区,单分区文件过大,查询扫描量高;分区过细,比如按用户ID分区,会产生大量小文件,元数据操作和列举成本反而上升。经验上,单个分区文件数量控制在几十到几百个、单文件大小在128MB到1GB之间比较理想。如果原始数据是流式小文件,应在清洗区通过合并任务压缩成较大Parquet文件。
文件格式:从JSON到Parquet的演进
原始区通常保留上游原貌,JSON、CSV、日志文本都可以,压缩方式推荐gzip或zstd,兼顾压缩率和可读性。清洗区开始引入列式格式,Parquet是默认选择,因为它支持列裁剪、谓词下推和高效压缩。可信区继续使用Parquet,并配合Glue Data Catalog或Lake Formation注册表结构,使Athena、Redshift Spectrum、EMR都能直接查询。消费区根据场景选择:面向BI的聚合表用Parquet,面向实时导出的可以用CSV或JSON,但应明确标注为导出格式而非分析格式。
一个常见的教学示例是:原始区每天到达约20GB的JSON订单数据,清洗后转为Parquet并压缩,体积通常降到3~5GB;可信区再做一次分区整理和列裁剪,扫描量进一步下降。这个比例不是固定值,但能说明格式选择对查询成本的影响。
生命周期管理:让数据按价值迁移
四层的数据价值随时间衰减速度不同。原始区需要长期保留以满足审计和重跑需求,但可以迁移到低频访问或归档存储;清洗区是中间产物,保留周期可以短一些,例如30~90天;可信区是核心资产,保留时间最长;消费区按业务需要保留,过期后可删除或重建。生命周期规则应直接绑定到前缀,例如:
raw/ → 30天后转STANDARD_IA,180天后转GLACIER
cleaned/ → 30天后转STANDARD_IA,90天后过期删除
trusted/ → 90天后转STANDARD_IA,365天后转GLACIER
consumption/ → 60天后过期删除(可按需重建)
这些参数是示例,实际应根据合规要求、重跑窗口和查询频率调整。关键原则是:生命周期规则要显式、可审计,并且与数据责任匹配,不要让原始区被意外删除,也不要让消费区长期占用高成本存储。
落地时的检查要点
在真正创建存储桶和生命周期规则之前,建议先确认几件事:原始区的写入是否只追加、不覆盖;清洗任务是否按分区幂等重写;可信区是否有明确的数据质量校验规则和失败处理路径;消费区的查询是否真的只扫描必要分区。如果使用Athena,可以通过 EXPLAIN 或查询统计查看扫描量,验证分区裁剪是否生效。如果使用Glue ETL,注意作业书签与分区覆盖的配合,避免重复处理或漏处理。
四层设计不是必须严格四层,小型场景可以合并清洗区和可信区,但“原始不可变、中间可重跑、消费可重建”这三个原则应当保留。目录规划、分区策略、文件格式和生命周期管理四者相互约束:分区决定扫描成本,格式决定存储与查询效率,生命周期决定长期成本,而目录结构决定这些规则能否被清晰表达和自动执行。