
开放表格式如何实现数据版本管理与时间旅行
来源标题:Open Table Formats Explained
开放表格式(如Delta Lake、Iceberg)通过每次写入生成独立快照,实现数据版本管理与时间旅行读取。行血缘和删除向量(Iceberg v3引入)让增量处理只需读取变更行,降低CDC管道成本。由于无限保留历史版本成本高昂,这些格式配套保留策略和vacuum/过期快照操作来清理不再引用的数据。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
数据版本化是开放表格式的一种能力,它保留每一次先前表状态的记录,而不是就地覆盖数据;时间旅行则通过版本号、快照 ID 或时间戳读取其中任一先前版本。开放表格式在设计上就支持时间旅行和数据集版本化,因为每次写入本就已创建一个新的、可独立寻址的快照或日志条目。
增量处理只读取自上次处理以来发生变更的行,而不是重新扫描整个数据集——这正是变更数据捕获(CDC)背后的模式,管道只消费应用到源表上的插入、更新和删除。行血缘和删除向量最初引入 Delta Lake,后通过 Iceberg v3 引入 Iceberg,使这一过程成本更低:行血缘跟踪自上次扫描以来哪些行发生了变化,删除向量则以紧凑的位图表示已删除的行,而不是重写数据文件。
无限期保留每一个历史版本代价高昂,因此开放表格式将版本化与保留策略以及 vacuum 或 expire-snapshots 操作配合使用,后者会移除保留窗口内不再被引用的数据。过于激进地运行 vacuum 可能会破坏仍在引用旧版本的时间旅行查询,因此窗口的设置要与可能需要进行时间旅行的最长运行查询相匹配。
生产表的合理节奏是将增量处理与摄取间隔匹配——流式数据摄取通常每 5 到 15 分钟一次——并将 vacuum 和快照过期设置为每日运行,避开查询高峰时段。
开放表格式通过分层组织的元数据管理来提升查询性能:清单文件或日志条目描述各个数据文件,快照或日志版本描述某一时间点的表状态,而目录则跟踪当前哪个版本具有权威性。如今,Unity Catalog 在企业部署中管理着超过 17 EB 的开放表格式数据——这让人得以一窥现代湖仓目录所管理的元数据规模。
随着表不断增长,清单文件和事务日志检查点本身也可能拖慢查询规划,因此维护工作应包括将清单重写为更少、更大的文件,并根据写入频率调整检查点间隔。Databricks 和开源社区正在开发跨 Delta Lake 和 Iceberg 的统一元数据结构,预计第三季度进入预览,它将 Delta Lake 的快速写入日志与 Iceberg 的快速读取清单树结合在一起。
元数据缓存——将最近访问的清单、检查点或目录响应保留在内存中——通过避免每次请求都完整遍历元数据树来降低重复查询的延迟,这对于针对同一批大表发出大量小查询的 BI 工作负载尤为重要。
Apache Iceberg、Delta Lake 和 Apache Hudi 都保证单表写入的可串行化隔离或快照隔离,因此并发读取者始终能看到一个完整、一致的版本,而绝不会看到部分写入。它们的差异在于协调机制:Iceberg 一直以目录作为事实来源,Hudi 使用自己的时间线服务,而 Delta Lake 在目录提交使其与目录协调模型对齐之前,依赖文件系统的原子性。
这三种格式都使用乐观并发控制:写入者不是在写入前锁定表,而是读取当前版本、准备变更,并且只有在期间没有其他写入者提交冲突变更时才提交。如果检测到冲突,事务会安全失败,要么针对更新版本重试,要么中止,绝不会让表处于不一致状态。
减少写入争用的最有效方法是缩小并发写入者之间的重叠:对摄取任务进行分区,使不同管道写入不同分区;将小写入批量合并为更少、更大的提交;并将合并操作限定在它们触及的分区上。目录提交在这里也有帮助,因为多表事务让相关更新一起提交,而不是作为来自多个进程的独立写入相互竞争。
Apache Iceberg 往往最适合多引擎读取访问最为重要的场景——组织从 Trino、Snowflake、Flink 和 Spark 并排查询相同的表。Delta Lake 最适合需要多表事务和细粒度治理的以 Spark 为中心的管道。Apache Hudi 最适合高频、记录级 upsert 工作负载,例如 CDC 复制,其专门构建的索引在此类场景中优于通用合并操作。
引擎兼容性应针对已投入生产的查询引擎进行评估,而不仅仅是看功能列表——一个技术上更优越的格式,如果缺少团队主要引擎的成熟连接器,带来的风险要多于它消除的风险。Delta Kernel 是一个用 Java 和 Rust 编写的开源库,已成为引擎添加 Delta Lake 支持而无需重新实现协议的常见方式;它已经为 DuckDB 和 ClickHouse 集成提供支持,而这两个实现正逐步统一到一个共享的 Rust 核心上。
在标准化采用某种格式之前,应针对一个有代表性的、中等杂乱的生产表进行概念验证:测量并发负载下的写入延迟,确认目标引擎原生读取该格式,而不是通过缓慢的连接器读取,并验证 schema 演进和时间旅行的行为符合预期。
目录是记录哪些表存在、其数据位于何处以及哪个快照具有权威性的记录系统——可选方案包括最初的 Hive Metastore、AWS Glue Data Catalog 和 Unity Catalog,后者在一套访问策略下统一管理 Delta Lake 和 Apache Iceberg 表。Delta Lake UniForm 更进一步,让单份 Delta Lake 数据无需重复存储即可被原生读取为 Iceberg 表,从而解决了促使团队推迟标准化的格式锁定顾虑。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。