过去十年,银行数据平台的架构经历了从"传统数仓"到"数据湖"再到"湖仓一体"的三次范式转移。传统数仓(如 Teradata、Greenplum)擅长结构化数据的规范化建模,但面对半结构化日志、图片、语音等非结构化数据时捉襟见肘;数据湖(如 HDFS + Parquet)虽然存储成本极低,但缺乏事务支持、Schema 演变和高效查询能力。湖仓一体(Lakehouse)试图用开放表格式(Iceberg / Hudi / Delta Lake)在数据湖上实现数仓能力,正在国内多家银行的下一代数据平台中推广。
银行为什么需要湖仓一体?
金融机构的数据有三个特征,恰好命中传统数仓和数据湖各自的软肋:
- 数据类型极杂:交易流水、客户画像、反欺诈图片、客服录音、PDF合同扫描件——结构化与非结构化高度混合;
- 历史数据极多:监管要求交易明细保留至少15年,传统数仓按TB计费,成本难以承受;
- 实时与离线并行:监管报送需要离线跑批,而实时风控需要流式处理,两套架构独立运维,成本高。
湖仓一体的核心承诺是"一份存储,多种计算引擎共享",通过 Iceberg / Hudi 的元数据层实现事务、Schema 演变和高效目录查询。
开放表格式对比:Iceberg vs Hudi vs Delta Lake
银行的选型通常围绕以下三个表格式展开:
| 特性 | Apache Iceberg | Apache Hudi | Delta Lake |
|---|---|---|---|
| 事务支持 | 快照隔离 | MVCC | ACID |
| Schema 演变 | 完整支持(add/rename/delete/reorder) | 支持 | 完整支持 |
| 时间旅行 | 原生支持 | 支持 | 原生支持 |
| 增量读取 | 支持 snapshots |
incremental query |
readStream |
| 隐藏分区 | 原生支持 | 不支持 | 不支持 |
| 主键约束 | 不支持(需应用层保证) | 原生主键/索引 | 原生主键 |
| 与 Spark 集成 | 优秀 | 优秀 | 原生 |
| 与 Flink 集成 | 1.15+ 原生 | 原生 | 需 Kafka Connect |
| 社区活跃度 | 全球活跃(Netflix、Apple) | Apache 孵化中 | Databricks 主导 |
选型建议:
- Iceberg:适合以离线分析为主、对 Schema 灵活性要求高的场景。某银行在Iceberg上存储了20年的历史交易数据,利用 Iceberg 的 Partition Evolution 能力随时按新的分区策略重组织数据。
- Hudi:适合存在大量 Upsert(更新插入)操作的场景,如客户画像每日增量刷新、贷后状态变更。Hudi 的 MOR(Merge On Read)表允许写入端仅写 delta 文件,查询时再做合并,写入吞吐极高。
- Delta Lake:适合已经深度绑在 Spark 生态的团队(如 Databricks 用户),但对其他引擎(如 Flink、Trino)的兼容性仍在追赶。
某国有大行的实践是:核心交易历史数据用 Iceberg(纯追加写,分区按月份演化),客户画像宽表用 Hudi(高频 Upsert),流式数据先用 Kafka 缓冲再统一写入 Hudi。
金融湖仓的架构设计
典型的银行湖仓一体架构如下:
[源系统层]
|
v
+-----------+ +-----------+
| Flume/ | | Debezium/ |
| DataX | | OGG CDC | --> 实时流
| (批量) | | (实时) |
+-----+-----+ +-----+-----+
| |
v v
[HDFS / OSS / S3] <--- 统一存储层
|
v
[Iceberg / Hudi 元数据层] <-- 表格式管理
|
+----------------+----------------+
| | |
v v v
[Spark/Flink ETL] [Trino/Presto 查询] [BI 工具]
(离线/实时处理) (即席分析) (Superset/QuickBI)
关键设计要点:
1. 存储格式统一为 Parquet Parquet 的列式存储、字典编码、Page 级压缩对银行的大宽表(上百列的客户画像表)极为友好。配合 Snappy 压缩,相较于 CSV 节省60%以上存储空间,且查询速度提升5倍以上。
2. 冷热分层 监管数据保留15年,但并非所有历史数据都需要高频访问。利用 HDFS 的 Storage Policy 或对象存储的生命周期管理: - 热数据(近1年):SSD存储,毫秒级访问; - 温数据(1-5年):SATA盘,秒级访问; - 冷数据(5年以上):低频归档存储,分钟级可恢复。
3. 权限一体化 传统数仓通过 Ranger/Hive Metastore 做表级/列级权限控制,数据湖因对象存储(OSS/S3)的扁平命名空间而权限管控困难。湖仓一体的解决思路是: - 通过 Sentry/Ranger 对 Trino/Spark 做统一权限管控; - 结合对象存储的 Bucket Policy,对冷数据所在的 Bucket 做网络隔离(仅内网数据平台的 VPC 可访问)。
湖仓一体的实战挑战
挑战一:小文件问题
银行每日凌晨会产生大量小时级/分钟级的增量数据文件。Hudi/Iceberg 表的底层一旦积累数百万个小文件(< 64MB),查询性能会急剧下降。
解决:配置 Hudi 的 InlineCompaction 或 Iceberg 的 RewriteDataFiles 作业,定期将小文件合并成大文件。某银行在每日日终跑批后触发一次Compaction,将小文件数量从日均10万+降到不足1万。
挑战二:Schema 漂移
银行核心系统变更频繁(每周可能有字段新增)。Iceberg 的 partition-spec-evolution 允许在保留历史分区数据的前提下,修改未来分区的分区字段,而不需要重写历史数据。这避免了传统 Hive"改分区就需要全表重刷"的噩梦。
挑战三:与遗留数仓共存
银行不可能一次性将所有数仓业务迁移到湖仓。某股份制行的做法是"双跑期":新数据同时写入传统 Hive 数仓和湖仓,下游应用逐步切换,切换完成后下线 Hive 链路。
总结
湖仓一体不是技术炫技,而是银行在"PB级数据规模 + 15年历史保留 + 实时离线一体"三重压力下的必然选择。对数据工程师而言,掌握 Iceberg 或 Hudi 的Internals(元数据文件结构、快照管理、Compaction策略)是进入下一代金融数据平台建设的入场券。