3. 数据湖目录结构与分区设计
数据湖最容易失控的地方,不是存储容量,而是“路径语义”。当不同团队各自按习惯把文件丢进容器,几个月后就会出现 /data/2023/final_v2/、/raw/customer_new/ 这类无法治理的路径。企业级目录规范的目标,是让路径本身携带可解析的业务域、数据层级、来源系统、时间与分区信息,使数据工程师、分析师和治理工具都能仅凭路径判断数据含义与生命周期阶段。
一、目录规范:用路径表达数据契约
推荐采用“容器/文件系统 → 数据层级 → 业务域 → 数据集 → 分区列”的层级结构。以 ADLS Gen2 为例,容器名对应环境与用途,目录名对应层级与业务语义:
abfss://lake-prod@companydatalake.dfs.core.windows.net/
bronze/ # 原始层,保留源系统原貌
sales/
orders/
source_system=erp/
ingest_date=2025-03-01/
part-00000.parquet
silver/ # 清洗整合层
sales/
orders_cleaned/
order_date=2025/03/01/
gold/ # 服务层,面向主题域
sales/
daily_sales_summary/
report_date=2025-03-01/
路径中的 bronze/silver/gold 是数据成熟度层级,sales 是业务域,orders 是数据集,source_system、ingest_date、order_date 是分区列。这种结构让路径成为可被 Spark、Synapse、Purview 自动解析的元数据来源。命名统一使用小写字母、数字和下划线,避免空格、中文和大小写混用,因为 Hive 风格分区在部分引擎中大小写敏感,混用会导致分区裁剪失效。
^abfss://lake-(dev|test|prod)@.+/ (bronze|silver|gold)/[a-z_]+/[a-z_]+/。二、分区策略:在裁剪效率与文件数量之间取平衡
分区的本质是把“扫描全表”变成“只扫描相关目录”。分区列选择应遵循三个原则:高基数、查询过滤频繁、数据分布相对均匀。日期通常是最优分区列;业务域、来源系统适合作为上层目录而非分区列;客户 ID、订单 ID 这类高基数字段不适合直接做分区,否则会产生海量小目录。
以订单事实表为例,若按 order_date 按天分区,每天约 200 万行、单文件 128 MB,则每天约 15~20 个文件,一年约 7000 个文件,属于健康范围。若再叠加 region 分区,每天 5 个区域,文件数变为 75~100 个/天,一年约 3 万个文件,仍可接受,但需评估元数据压力。若继续叠加 channel,文件数会迅速膨胀到数十万,此时应改用 Z-Order 或 Liquid Clustering 等文件内聚技术,而不是继续增加分区列。
三、文件格式选择:按层级匹配能力
Bronze 层应尽量保留源系统原始格式,例如 ERP 导出的 JSON、CSV 或 Avro,以便在解析逻辑出错时重新处理。Silver 层统一转换为 Delta Parquet,因为 Delta Lake 提供 ACID 事务、时间旅行和 Schema 演进,能支撑清洗、去重和合并操作。Gold 层继续使用 Delta,但应控制文件大小在 128 MB~1 GB 之间,避免过多小文件拖慢 BI 查询。
Parquet 的列式存储使查询只读取必要列,配合分区裁剪可显著降低 I/O。对于需要频繁更新的维度表,Delta 的 MERGE 比覆盖写更高效;对于只追加的事实表,直接 INSERT 即可。若使用 Synapse 无服务器 SQL 池直接查询文件,需注意 Parquet 的嵌套类型支持较好,而 CSV 需要显式定义 Schema。
四、生命周期管理:让数据自动降温
生命周期策略应基于“访问频率 + 合规要求”制定。以 ADLS Gen2 为例,可在容器或目录级别配置生命周期管理规则:
{
"rules": [
{
"name": "bronze-to-cool",
"enabled": true,
"type": "Lifecycle",
"definition": {
"filters": {
"blobTypes": ["blockBlob"],
"prefixMatch": ["bronze/sales/orders/"]
},
"actions": {
"baseBlob": {
"tierToCool": { "daysAfterModificationGreaterThan": 30 },
"tierToArchive": { "daysAfterModificationGreaterThan": 365 },
"delete": { "daysAfterModificationGreaterThan": 2555 }
}
}
}
}
]
}
该规则表示:Bronze 层订单数据 30 天未修改转入冷层,365 天转入归档层,7 年后删除。Silver 和 Gold 层因访问频率较高,可设置更长的热层保留期,例如 90 天转冷、730 天归档。归档层的数据读取延迟较高,适合合规留存而非日常分析。
_delta_log 会持续更新,可能导致整个表被误判为热数据。建议对 Delta 表按分区目录分别设置规则,或使用 Delta 的 VACUUM 与保留策略配合,避免归档层数据被意外删除。五、落地检查清单
| 检查项 | 合格标准 | 常见问题 |
|---|---|---|
| 路径命名 | 小写、下划线、无空格 | 大小写混用导致分区裁剪失效 |
| 分区列 | 日期 + 低基数业务列,不超过 3 个 | 用客户 ID 分区产生海量小目录 |
| 文件大小 | 128 MB~1 GB | 流式写入产生大量 KB 级文件 |
| 格式 | Silver/Gold 使用 Delta Parquet | Gold 层仍用 CSV 导致 BI 查询慢 |
| 生命周期 | 按层级和访问频率分层配置 | 全湖统一 30 天删除,误删合规数据 |
目录结构与分区设计不是一次性任务,而是随数据增长持续调优的过程。建议每季度检查一次分区文件数量、平均文件大小和冷热数据分布,当发现某分区日均新增文件超过 200 个或平均文件小于 32 MB 时,就应触发合并或重新评估分区策略。把路径、分区、格式和生命周期四者绑定为统一规范,数据湖才能从“文件堆”变成可治理、可演进的资产平台。