Apache Iceberg 表格式介绍
Apache Iceberg 是一种设计用于管理大型、缓慢变化数据集的表格式,支持 ACID 事务、可扩展性、动态 Schema 评估和存储分离。其核心组件包括:
- Catalog:提供原子性能力,支持 HiveCatalog、HadoopCatalog 等实现。
- TableMetadata:存储表的元数据,每次更新生成新的 TableMetadataSnapshot。
- ManifestList:记录数据更新操作,生成新的 Snapshot。
- DataFile/DeleteFile:存储在分布式文件系统中的实际数据文件。
Iceberg 的 ACID 特性
Iceberg 通过以下机制保证 ACID 事务:
- 原子性:Catalog 保证表元数据的更新是原子性的。
- 一致性:通过 Snapshot 和 Manifest 机制确保数据一致。
Iceberg 动态 Schema 评估
- Schema Evaluation:支持并发修改表 Schema(增加/删除/修改列),无需改变写入数据格式。
- Partition Evaluation:支持动态分区,如建表时定义分区列(示例:按月份分区),写入数据时无需包含分区列,更新分区后同样无需改变写入格式。
Spark 读写 Iceberg
Spark 写入 Iceberg 表
写入过程包括:
- DataFileInputSource 读取数据。
- WriteTask 将数据写入 DataFile。
- WriteCommit 提交写入操作,生成新的 Snapshot。
Spark 读取 Iceberg 表
读取过程包括:
- Plan Task 根据分区摘要(Partition Summary)和指标(Metrics)过滤数据文件。
- Execute Task 执行过滤,仅读取符合条件的 DataFile。
Iceberg 文件过滤机制
- Partition 过滤:通过记录 DataFile 的分区 spec ID,结合查询条件生成分区过滤条件。
- MOR (Multi-Point OR) 删除:支持基于文件位置或值进行删除,通过 DeleteFile 记录已删除文件。
Upsert 机制
- COW (Copy-On-Write):更新数据时复制原文件,生成新的 DataFile。
- MOR:更新数据时生成新的 DataFile 和 DeleteFile,更高效。
Iceberg 生产实践挑战与优化
挑战
- 宽表:Spark commit 时可能收集大量 DataFile 到 Driver,存储空间随列增加而增加。可通过设置 Table Properties 记录列的 Metrics(如列大小、值分布等)优化。
- Schema 变动频繁:频繁 Schema 变更可能导致性能问题。可通过设置
write.spark.accept-any-schema 为 true 并启用 merge-schema 选项优化。
- Schema 影响文件过滤:Schema 变动可能导致过滤效率降低。可通过记录 SchemaID 优化文件过滤。
优化措施
- 基于 Schema 过滤文件:在 ManifestFile 和 DataFile 中添加 SchemaID 字段,根据 SchemaID 过滤文件。
- 其他优化:ZOrder 优化文件布局、Parquet Bloom Filter、Iceberg 索引、优化 Parquet Vectorized Read Decimal、多线程并发删除文件、View 支持。
数据治理服务
数据治理服务总览
- Expire Snapshots:定期清理过期 Snapshot,释放存储空间。
- 合并小文件:通过 BinPack、Sort、ZOrder 等方法合并小文件,减少文件数量。
- 列生命周期管理:自动管理列的生命周期,如自动删除低使用率列、清理过期数据。