Apache Hudi 1.0 引入了新的 LSM 时间线,以扩展长期表的元数据管理。通过将时间线存储重构为紧凑的版本化树布局,Hudi 实现了更快的元数据访问、快照隔离和对非阻塞并发控制的支持。
Apache Hudi 架构的核心是 Timeline[1] - 一个日志结构的系统,在任何时间点充当表状态的单一事实来源。时间线记录了对 Hudi 表执行的每项更改和作,包括写入、架构演变、压缩、清理和聚簇操作。这种细致的记录保存使 Hudi 能够提供 ACID 保证[2]、强大的并发控制[3]以及增量处理、回滚/恢复和时间旅行等高级功能。
从本质上讲,时间线的功能类似于预写日志 (WAL),[4] 维护一系列不可变的操作。每个操作都记录为一个唯一的 Instant,一个由其操作类型(例如,commit、clean、compaction)标识的工作单元、一个标记作启动时间的时间戳及其生命周期状态。在 Hudi 中, instant是指操作、时间戳和状态(REQUESTED、INFLIGHT 或 COMPLETED)的组合,并用作时间轴上更改的原子单位。这些时间线条目是 Hudi 事务完整性的支柱,确保每个表更改都被原子记录并且时间线一致。每个作都经历一个状态生命周期:
这些时刻既用作日志条目,又用作事务标记,准确定义在任何给定时间哪些数据是有效和可见的。无论是为最新视图发出快照查询,运行增量查询以获取自上一个检查点以来的更改,还是回滚到以前的状态,时间线都可以确保精确跟踪每个作的影响。每个操作 (例如提交、清理、压缩或回滚)都会被显式记录,从而允许计算引擎和工具精确推理表的状态转换和历史记录。这种严格的排序和生命周期管理也支持 Hudi 提供可序列化隔离(ACID 中的“I”)保证的能力,确保读者只观察提交的数据和一致的快照。
为了优化性能和长期存储可扩展性,Apache Hudi 将时间线分为两个不同的组件,它们协同工作以提供对最近作的快速访问,同时确保有效保留历史记录。
活动时间线[5]是 Hudi 事务日志的第一行。它包含最近和正在进行的操作,这些作对于构建一致且最新的表视图至关重要。每次启动新作(如数据写入、压缩、清理或回滚)时,都会立即将其记录为 .hoodie/
目录下的新即时文件。这些文件都包含有关作生命周期的元数据,在 REQUESTED → INFLIGHT → COMPLETED 的标准状态之间移动。
系统会不断查阅活动时间线 - 无论是发出查询、运行压缩还是计划新的写入操作。计算引擎从活动时间轴中读取数据,以确定哪些数据文件有效且可见,使其成为表最新状态的真实来源。为了保持性能,Hudi 在活动时间轴上强制执行保留策略,即它故意只保留最近作的窗口,确保时间轴保持轻量级和快速扫描。
随着时间的推移,表自然会累积更多的操作,尤其是在高写入或更新环境中。随着 instants 数量的增加,如果不加以控制,活动时间轴可能会变得臃肿,从而在读取和写入过程中引入延迟和性能损失。
为了解决这个问题,Hudi 实施了一个存档过程。一旦活动时刻的数量超过配置的阈值,较旧的作就会从活动时间轴卸载到存储在 .hoodie/archive/
目录中的 Archived Timeline 中。此设计可确保在活动时间线保持精简和快速以进行日常作的同时,仍会保留表的完整事务历史记录,以用于审计、恢复和时间旅行目的。
尽管存档时间线针对长期保留进行了优化,但访问深度历史记录可能会导致更高的延迟和开销,尤其是在具有大量存档时刻的工作负载中。正是这种限制为 Hudi 1.0 中引入的 LSM Timeline 创新奠定了基础。
Apache Hudi 的原始时间线设计适用于许多工作负载。通过维护轻量级活动时间线以实现快速作并将历史即时卸载到存档中,Hudi 在性能和持久性之间取得了平衡。但是,在之前的时间轴设计中,有一些方面需要考虑。
为了克服原始时间线架构的扩展挑战,Apache Hudi 1.0 引入了 LSM(日志结构化合并)[6] 时间线——一种存储和管理时间线元数据的全新方法。这种重新设计将日志结构存储[7]、分层压缩和快照版本控制的原则结合在一起,以提供高度可扩展的云原生解决方案来跟踪表历史记录。
Hudi 在时间轴上的表示方式引入了一个关键变化。以前,Hudi 将时间视为瞬时,即每个动作似乎都在一瞬间生效。虽然该模型对基本作有效,但在实施某些高级功能(如非阻塞并发控制 (NBCC)[8])时被证明是有限的,这些功能需要将作推理为时间间隔来检测重叠和解决冲突。
为了解决这个问题,Hudi 时间轴上的每个作现在都会记录请求时间 (作启动时)和完成时间 (完成时)。这使 Hudi 不仅可以跟踪作的调度时间,还可以跟踪它如何随着时间的推移与其他并发作交互。为了确保分布式流程之间的全局一致性,Hudi 正式确定了 TrueTime 语义[9]的使用,保证了所有即时时间都是单调递增的和全局有序的。这是精确冲突检测和健壮事务隔离的基本要求。
从本质上讲,LSM 时间线用分层树结构取代了平面存档模型,使 Hudi 能够有效地管理数百万个历史时刻的元数据,而不会影响读取性能或一致性。它是这样设计的:
${min_instant}_${max_instant}_${level}.parquet
其中 min_instant
和 max_instant
表示文件中的时刻范围, 级别
表示层(例如,L0、L1、L2)。LSM 时间线在 Apache Hudi 处理元数据的方式方面取得了重大进步,提供了性能改进和新功能。
LSM 时间线代表了 Apache Hudi 时间线架构中的自然进展,旨在满足对大规模和长期表不断增长的需求。Hudi 的时间线一直是事务完整性、时间旅行和增量处理功能的基础。基于 LSM 的新设计通过引入具有清单驱动快照隔离的分层压缩结构来增强可扩展性和运营效率。这一改进使 Hudi 能够更有效地管理广泛的元数据历史记录,保持可预测的性能,并更好地支持非阻塞并发控制等高级使用案例。
[1]
Timeline:https://hudi.apache.org/docs/timeline
[2]
ACID 保证:https://www.onehouse.ai/blog/acid-transactions-in-an-open-data-lakehouse
[3]
并发控制:https://hudi.apache.org/blog/2025/01/28/concurrency-control
[4]
预写日志 (WAL),:https://en.wikipedia.org/wiki/Write-ahead_logging
[5]
活动时间线:https://hudi.apache.org/docs/timeline#active-timeline
[6]
LSM(日志结构化合并):https://hudi.apache.org/docs/timeline#timeline-components
[7]
日志结构存储:https://en.wikipedia.org/wiki/Log-structured_merge-tree
[8]
非阻塞并发控制 (NBCC):https://hudi.apache.org/blog/2024/12/06/non-blocking-concurrency-control/
[9]
TrueTime 语义:https://hudi.apache.org/docs/timeline#truetime-generation