讲讲Paimon的写数据详细流程
基于 Apache Paimon 最新官方文档,其写数据的详细流程主要围绕 LSM 树(Log-Structured Merge-tree)存储结构 和 双阶段提交(Two-Phase Commit)的架构设计展开。以下是 Paimon 写入数据的核心角色分工和详细流转步骤。
一、 核心角色分工
在 Flink 写入 Paimon 的典型流(Stream)模式下,算子拓扑采用“并发写入,串行提交(concurrent write, serial commit)”的设计:
- Paimon Sink (Writer):并发运行。为了避免同一个 Bucket 的冲突,Paimon 通常通过 Hash 将数据路由到指定的 Task。每个 Writer 独立负责其 Bucket 内的数据缓冲、排序落盘以及后台异步合并(Compaction)。
- Committer Operator:单例算子(Singleton)。它负责协调所有并发 Writer 发送的元数据,统一在 Flink Checkpoint 期间进行事务性提交并触发快照过期逻辑。
二、 详细写数据步骤
Paimon 的写数据流程可以拆分为以下 5 个步骤:
步骤 1:内存缓冲(MemTable)
- 新写入的数据首先被写入内存中基于堆(Heap-based)的 LSM 树缓冲区(Write Buffer / MemTable)。
- 如果开启了
local-merge-buffer-size,在被路由到具体的 Bucket 写入之前,数据会在本地进行一次预合并,以缓解由于主键倾斜带来的性能瓶颈。
步骤 2:数据落盘(Flush)
- 当内存缓冲区满,或者 Flink 即将触发 Checkpoint 时,Writer 会触发落盘(Flush)。
- 数据在内存中根据主键(Primary Key)进行排序,然后以列式格式(如 ORC、Parquet)刷写到磁盘中,形成一个个新的数据文件(Data File)。
- 注意:每个写入的数据文件都是一个有序的 Sorted Run。此时落盘仅是物理文件的生成,尚未更新元数据,对外部读取仍旧不可见。
步骤 3:后台异步合并与 Changelog 生成(Asynchronous Compaction)
- 随着多次 Flush 的进行,小文件(Sorted Runs)不断增多。为了防止读取时多路归并合并的开销过大,Writer 内部的
CompactManager会在后台异步触发 Compaction。 - Compaction 过程:后台线程会将多个小的 Sorted Runs 合并成一个更大的、无重叠范围的有序 Sorted Run,以此来减少 L0 文件的层数。
- 附加生成文件:
- Changelog 文件:根据配置的
changelog-producer(如input、lookup、full-compaction等),在此阶段可能双写或在合并时生成 Changelog 文件,供下游流式读取。 - Deletion Vector(MOW 模式):若在 Merge-On-Write 模式下,合并时还会查询 LSM 树并为被覆盖/删除的数据生成 Deletion Vector 文件,以便在读取时直接过滤。
- Changelog 文件:根据配置的
步骤 4:生成与发送 Committable
- 在 Flink Checkpoint 协调器发起 Checkpoint 时,Writer 会强制将当前内存中所有缓冲的记录刷写落盘。
- 随后,Writer 将当前 Checkpoint 周期内产生的新数据文件、Changelog 文件信息,以及异步合并产生的历史文件变更信息,封装成一个
committable消息,发送给下游的Committer Operator。
步骤 5:元数据提交与 Snapshot 生成(Commit)
当单例的 Committer Operator 收到所有并发 Writer 的 committable 消息后,串行地执行事务提交:
- 写入 Manifest:首先将这些新增(ADD)或逻辑删除(DELETE)的文件变更信息写入到新的 Manifest 文件(Avro 格式)中。
- 写入 Manifest List:将当前快照关联的所有 Manifest 文件路径和分区统计信息打包汇总,写入到一个新的 Manifest List 文件(Avro 格式)。
- 创建 Snapshot 文件:最后,Paimon 抢占下一个快照 ID,在
snapshot目录下创建一个包含该快照完整定义的 JSON 文件(例如snapshot-N),并更新LATEST提示文件。至此,新数据正式对外界可见。- 注:在一个 Checkpoint 周期内,如果既有新数据写入,又有后台 Compaction 完成,Committer 可能会提交生成两个 Snapshots(一个是数据写入产生的
Append类型快照,另一个是合并产生的Compact类型快照)。
- 注:在一个 Checkpoint 周期内,如果既有新数据写入,又有后台 Compaction 完成,Committer 可能会提交生成两个 Snapshots(一个是数据写入产生的
三、 辅助流程:快照过期与物理清理(Snapshot Expiration)
在提交完新 Snapshot 后,Committer 会自动触发快照过期流程,以避免历史文件无限膨胀:
- 计算出需要保留的 Snapshot 范围。
- 扫描已过期的快照,找出其中被标记为
DELETE且在后续有效快照中没有被再次使用的旧数据文件。 - 物理清理:将这部分已被完全废弃的数据文件、Changelog 文件和对应的 Manifest 文件在底层分布式文件系统(如 HDFS、S3)中执行物理删除。