摘要:

本篇是 Apache Paimon 专栏的收尾,也是三个数据湖专栏(Apache HudiApache Iceberg、Apache Paimon)的最终汇总。经过对 Paimon 的 LSM-Tree 存储引擎、双表模型、Changelog Producer 和 Lookup Join 的深度解析,本文将从流存储能力这个 Paimon 的核心差异化维度出发,对四大方案(包含 Delta Lake)做全面的架构级对比。重点不在于”谁更好”,而在于理解每个方案在什么约束条件下是最优解——特别是在实时数仓、流批一体这个 Paimon 最强的赛道上,四者之间的差距到底有多大,体现在哪些具体的工程细节上。


第 1 章 从存储模型出发理解四者的根本差异

1.1 四种存储哲学

理解四大数据湖方案的所有架构差异,最本质的入口是它们的存储模型

Delta Lake:不可变 Parquet 文件 + 事务日志
  → 核心设计决策:用事务日志保证 ACID,文件本身不可变
  → 写入=创建新文件,更新=替换旧文件(或 MoR 的变更文件)
  → 适合:批处理 ETL + 偶发 DML,Spark 平台的核心存储

Apache Hudi:不可变 Parquet 文件 + Record-Level Index + Timeline
  → 核心设计决策:在不可变文件之上建立记录级索引,支持高效 Upsert
  → 写入=Index 路由后更新对应文件(CoW)或追加日志(MoR)
  → 适合:高频 CDC Upsert,增量数据消费

Apache Iceberg:不可变 Parquet 文件 + 多层元数据规范
  → 核心设计决策:表格式规范与引擎解耦,Hidden Partitioning
  → 写入=追加新文件,更新=CoW 或 Row-level Delete File
  → 适合:多引擎互操作,大规模批处理,云原生数据湖标准

Apache Paimon:LSM-Tree(MemTable + 分层 SST)
  → 核心设计决策:用 LSM-Tree 替代 CoW,实现内存级写入速度
  → 写入=先进 MemTable(内存),定期刷写 SST(磁盘),后台 Compaction
  → 适合:高频流式 Upsert,秒级数据新鲜度,Flink 实时数仓

这四种存储哲学决定了它们在各个场景下的性能边界。

1.2 流式写入延迟的代际差异

这是 Paimon 最核心的差异化优势,值得用量化数据来精确描述:

场景:Flink 消费 Kafka,写入数据湖,要求端到端延迟最低

Delta Lake(Spark Streaming):
  Flink Checkpoint 间隔:5 分钟
  每次 Commit 生成的文件:10-50 个 Parquet(视数据量)
  端到端延迟:5-15 分钟
  限制:Commit 必须等 Checkpoint,Checkpoint 间隔是延迟下限

Hudi MoR(Flink Sink):
  Flink Checkpoint 间隔:5 分钟(调到 1 分钟会产生大量小文件)
  每次 deltacommit:若干 .log 文件(轻量)
  端到端延迟:3-10 分钟
  限制:deltacommit 必须等 Checkpoint,同样受限

Iceberg(Flink Sink):
  Flink Checkpoint 间隔:5 分钟
  每次 Commit:若干 Parquet + 新 Manifest
  端到端延迟:5-15 分钟
  限制:同 Delta Lake

Paimon(Flink Sink):
  Flink Checkpoint 间隔:5 分钟(用于 exactly-once 保证)
  MemTable Flush 间隔:每隔 N 秒(当 MemTable 满 256MB)
  数据可见性更新:每次 MemTable Flush 后发布 Snapshot(独立于 Checkpoint)
  端到端延迟:10-60 秒(Snapshot 发布与 Checkpoint 解耦)
  这是 Paimon 相比其他三者的决定性差异

为什么 Paimon 能做到解耦,而其他三者不行?

根本原因在于 LSM-Tree 的 MemTable:Paimon 的 MemTable 在 Flink 的 Operator State 中持久化(Checkpoint 时快照),所以即使 Checkpoint 尚未完成,MemTable 中的数据也是安全的(即使崩溃也能从 Checkpoint 恢复)。因此,Paimon 可以在 MemTable 写满后立即刷写到 SST 并发布 Snapshot,不需要等待 Checkpoint。

其他三者(Delta/Hudi/Iceberg)的写入数据存在 Flink 外部(S3/HDFS 上的 Parquet 文件)。在 Checkpoint 完成之前,这些文件的”可提交性”无法保证(崩溃后可能是部分写入的不完整文件)。所以它们必须等 Checkpoint 完成后才能安全 Commit。


第 2 章 四大方案的多维度深度对比

2.1 流式写入能力对比

维度PaimonHudiIcebergDelta Lake
数据可见延迟10-60 秒3-10 分钟5-15 分钟5-15 分钟
Flink 原生支持最优(原生设计)良好良好需要 Delta-Flink 连接器
高频 Upsert 吞吐高(MemTable 内存写)高(MoR 日志追加)中(CoW 或 Delete File)中(CoW 或 Deletion Vector)
Changelog 生成原生(Full/Lookup)有限(Incremental Query)实验性(Changelog View)CDF(需建表时开启)
小文件控制LSM-Tree 自动分层(后台 Compaction)Inline Compaction 可选Rewrite Data FilesOPTIMIZE 命令
Exactly-Once✅ 与 Flink Checkpoint 集成

2.2 存储与查询能力对比

维度PaimonHudiIcebergDelta Lake
主键 Upsert✅ LSM-Tree 原生✅ Index 路由⚠️ CoW(写放大)⚠️ CoW(写放大)
聚合存储(SUM/MAX 等)✅ AggregateMerge
部分字段更新✅ PartialUpdateMerge❌(需要 MERGE)
Time Travel✅ Snapshot 历史✅ Timeline✅ Snapshot✅ Delta Log 版本
多引擎支持中(Flink 最优,Spark/Trino 可用)中(Spark 最优)最优(规范统一)中(Spark 最优)
列式查询效率高(ORC/Parquet)高(Parquet)高(Parquet)高(Parquet)
分区演进有限有限✅ Hidden Partitioning有限

2.3 运维复杂度对比

维度PaimonHudiIcebergDelta Lake
Compaction 必要性必须(LSM-Tree 维护)重要(MoR)可选(优化)可选(优化)
后台任务管理内嵌 Flink Job独立 Compaction Job手动触发手动触发
Schema 演进支持支持(受 Avro 限制)最完善(列 ID)良好
多 Catalog 支持中(Flink Catalog)最优(REST Catalog)
云原生集成中(主要是阿里云)最优(AWS/GCP/Snowflake)中(Databricks 平台)
社区生态规模中(快速增长)

第 3 章 实时数仓场景的完整技术栈分析

3.1 Lambda 架构 vs 流批一体架构

传统的大数据架构采用 Lambda 架构:实时层(Kafka + Flink)和批处理层(Hive/Spark)并行运行,最终数据由 Serving 层合并:

Lambda 架构(传统):
  实时层:Kafka → Flink → HBase/Redis(实时结果)
  批处理层:HDFS → Spark → Hive/Parquet(离线结果)
  Serving 层:合并两层结果(复杂!)

问题:
  双路维护:相同业务逻辑需要用 Flink 和 Spark 各写一遍
  结果不一致:实时层和批处理层的计算逻辑可能有偏差
  运维复杂:两套系统的监控、告警、故障处理

流批一体架构(基于 Paimon)

流批一体架构(Paimon):
  唯一的存储层:Paimon 数据湖
    → Flink 流式写入(秒级延迟)
    → Spark/Trino 批量读取(历史分析)
    → Flink 流式读取 Changelog(下游计算)
  
  消除了实时层和批处理层的分离:
    → 同一份数据,流读 = 实时 Changelog,批读 = 历史快照
    → 相同的业务逻辑只需写一遍(Flink SQL)
    → 运维单点:只需维护 Paimon 表 + Flink Job

3.2 四层实时数仓的完整选型


graph TD
    subgraph "数据源"
        MySQL["MySQL/Oracle</br>(在线业务库)"]
        Kafka["Kafka</br>(事件流)"]
        Log["应用日志</br>(行为埋点)"]
    end

    subgraph "ODS 层 (原始数据)"
        ODS1["Paimon 追加表</br>MySQL CDC 原始事件</br>保留完整变更历史"]
        ODS2["Paimon 追加表</br>Kafka 事件流</br>按天分区,追加存储"]
    end

    subgraph "DWD 层 (明细数据)"
        DWD["Paimon 主键表</br>DeduplicateMerge</br>Lookup Changelog Producer</br>秒级数据新鲜度"]
    end

    subgraph "DWS 层 (汇总数据)"
        DWS_RT["Paimon 主键表</br>AggregateMerge (SUM/MAX)</br>实时指标存储"]
        DWS_Batch["Iceberg 表</br>复杂历史分析</br>Trino OLAP 查询"]
    end

    subgraph "应用层"
        BI["BI 报表</br>(Trino/StarRocks)"]
        RT["实时大屏</br>(API 直读 Paimon)"]
        ML["机器学习</br>(Spark 批量读取)"]
    end

    MySQL --> ODS1
    Kafka --> ODS2
    Log --> ODS2
    ODS1 --> DWD
    ODS2 --> DWD
    DWD --> DWS_RT
    DWD --> DWS_Batch
    DWS_RT --> RT
    DWS_RT --> BI
    DWS_Batch --> BI
    DWS_Batch --> ML

    classDef paimon fill:#6272a4,stroke:#bd93f9,color:#f8f8f2
    classDef iceberg fill:#44475a,stroke:#50fa7b,color:#f8f8f2
    classDef source fill:#282a36,stroke:#ffb86c,color:#ffb86c
    classDef app fill:#282a36,stroke:#8be9fd,color:#8be9fd
    class ODS1,ODS2,DWD,DWS_RT paimon
    class DWS_Batch iceberg
    class MySQL,Kafka,Log source
    class BI,RT,ML app

分层选型逻辑

ODS 层 → Paimon 追加表
  理由:ODS 是原始数据,只追加,不更新
        Paimon 追加表最轻量,与 Flink CDC 无缝集成
        保留完整的 CDC 原始事件(+I/-U/+U/-D)

DWD 层 → Paimon 主键表(Lookup Changelog)
  理由:DWD 是清洗后的最新状态,需要 Upsert(按主键)
        Lookup Changelog 提供秒级延迟的 Changelog 给下游
        Lookup Join 支持实时维表关联

DWS 实时指标层 → Paimon 主键表(AggregateMerge)
  理由:实时指标(UV、GMV、转化率)需要秒级更新
        AggregateMerge 在存储层维护聚合结果,避免重复全量计算
        直接支持 API 查询(低延迟点查)

DWS 批量分析层 → Iceberg
  理由:复杂的历史分析(如跨年的用户行为分析)需要多引擎访问
        Iceberg 的 Trino 集成最完善,分析查询性能最优
        Hidden Partitioning 简化运维

第 4 章 Paimon 的局限与适用边界

4.1 Paimon 不应该做什么

清晰地理解 Paimon 的局限,与理解它的优势同样重要:

❌ 不适合替代 Iceberg 做多引擎数据湖标准
  Paimon 的 REST Catalog 标准化程度不如 Iceberg
  Trino 对 Paimon 的支持不如对 Iceberg 完善
  云厂商(AWS Athena、Google BigQuery)没有 Paimon 的原生集成

❌ 不适合在非 Flink 技术栈中部署
  Paimon 的 Spark 支持存在,但不如 Flink 原生
  如果技术栈是纯 Spark(Databricks),Delta Lake 更好

❌ 不适合要求极低 Compaction 运维负担的场景
  LSM-Tree 的 Compaction 是必选项,不可禁用
  如果运维团队无法保障 Compaction Job 的稳定运行,
  LSM-Tree 会退化(L0 文件积累,查询变慢)

❌ 不适合超大规模批处理(PB 级全量 ETL)
  Paimon 的元数据结构不如 Iceberg 的三层 Manifest 在超大规模下高效
  对于 PB 级的历史数据管理,Iceberg 更稳健

4.2 Paimon 在实时数仓中无可替代的价值

✅ 秒级数据可见延迟
  其他三者在 Flink 场景下无法突破分钟级的 Checkpoint 延迟
  Paimon 通过 MemTable 与 Snapshot 发布的解耦,实现秒级延迟
  这是实时大屏、实时风控场景的基础设施要求

✅ 存储层聚合(AggregateMerge)
  其他三者的存储层不支持聚合函数(SUM/MAX/HyperLogLog)
  下游每次查询都需要 GROUP BY 全量重算
  Paimon 的 AggregateMerge 将聚合结果持久化在存储层,
  查询直接读取聚合值(相当于物化视图,但实时更新)

✅ Changelog 原生生产(Full Compaction / Lookup)
  其他三者的 Changelog 能力是后加的(CDF、Incremental Query)
  Paimon 的 Changelog 是核心设计的一部分
  与 Flink 的 Changelog 语义(+I/-U/+U/-D)完全对齐

✅ 维表 Lookup Join(替代 HBase)
  内置 Lookup Cache 机制,直接支持 Flink Lookup Join 语法
  不需要单独维护 HBase 集群
  维表同时支持批量 OLAP 查询(HBase 不行)

第 5 章 四大方案的最终选型建议

5.1 一张决策矩阵

你的主要需求最佳方案次优方案说明
实时数仓,秒级延迟PaimonHudi MoRPaimon 是唯一真正突破分钟级限制的方案
Flink CDC → 数据湖PaimonHudiPaimon 原生设计,Hudi 性能次之
实时指标聚合(SUM/UV)Paimon无直接对比AggregateMerge 是 Paimon 独有能力
高频 CDC Upsert(分钟级可接受)HudiPaimonHudi 的 Index + MoR 吞吐更高
多引擎数据湖(Spark+Trino+Flink)IcebergHudiIceberg REST Catalog 是标准
云原生(AWS/GCP)IcebergDeltaIceberg 云厂商集成最广
Databricks 平台Delta LakeIceberg平台原生,DLT/Photon 优化
分区演进(无缝修改分区方案)Iceberg无直接对比Hidden Partitioning 是 Iceberg 独有
Spark + 历史批量 ETLDelta Lake/IcebergHudi CoWPaimon 不是批处理的最优选
流批一体(Flink 主导)PaimonHudi实时链路 Paimon 最优,批量分析可搭配 Iceberg

5.2 三专栏技术栈汇总

回顾三个专栏覆盖的技术版图:

数据湖"四剑客"的定位总结:

Delta Lake(专注平台):
  最适合 = Databricks 平台 + Spark 技术栈
  核心能力 = DML 事务、Z-Order 优化、DLT 管道
  设计DNA = "给数据湖加 ACID,与 Spark 深度融合"

Apache Hudi(专注写入):
  最适合 = CDC Upsert 高吞吐 + 增量消费 ETL
  核心能力 = Record-Level Index(Bloom/Bucket)、Incremental Query、MoR
  设计DNA = "记录级 Upsert 是数据湖最难的问题,我来解决"

Apache Iceberg(专注规范):
  最适合 = 多引擎数据湖 + 云原生 + 大规模批处理
  核心能力 = 三层元数据、Hidden Partitioning、REST Catalog
  设计DNA = "开放表格式规范,让所有引擎平等地读写数据湖"

Apache Paimon(专注实时):
  最适合 = Flink 实时数仓 + 秒级延迟 + 流批一体
  核心能力 = LSM-Tree、Changelog Producer、AggregateMerge、Lookup Join
  设计DNA = "让数据湖原生支持流存储,彻底消除实时 vs 批量的架构鸿沟"

小结:Paimon 专栏总结

本专栏六篇文章,从 Flink 实时写湖的延迟困境出发,系统解析了 Paimon 如何用 LSM-Tree 突破这个困境:

篇章核心要点
01Checkpoint 周期是分钟级延迟的根本原因;Paimon 通过 MemTable 解耦写入与可见性
02MemTable(SortBuffer)+ 分层 SST + Full/Universal Compaction 的三层 LSM-Tree 实现
03主键表(LSM-Tree,Upsert)vs 追加表(不可变文件,仅追加);MergeFunction 的四种模式
04Full Compaction Changelog(分钟级延迟,高精确性)vs Lookup Changelog(秒级延迟,有写入开销)
05Paimon 作为 Flink Lookup Join 的维表:LRU Cache、全量 Cache 策略;替代 HBase 的适用边界
06四大数据湖方案的流存储能力全面对比;实时数仓分层选型:Paimon(ODS/DWD/实时 DWS)+ Iceberg(批量 DWS)

三专栏的最终总结:Hudi、Iceberg、Paimon 三者不是竞争关系,而是互补关系——它们解决的是数据湖建设中三个不同层次的核心问题(写入效率、格式标准、实时性)。在真实的大型数据平台中,很可能同时使用这三者(甚至加上 Delta Lake),每层数据选择最适合的方案。理解它们各自的设计取舍,是做出正确架构决策的基础。

思考题

  1. Paimon 的核心差异化是”流式写入延迟最低”——基于 LSM-Tree 的秒级可见性远优于 Delta/Iceberg 的分钟级延迟(取决于 Compaction 频率)。但 Paimon 的 LSM 架构带来了额外的运维复杂性(需要管理 Compaction 策略、多层文件结构)。在一个以 Flink 为核心计算引擎、需要同时支持实时写入和 OLAP 查询的数据平台中,Paimon 的运维复杂性代价是否值得为其低延迟特性买单?
  2. 四种格式(Delta、Iceberg、Hudi、Paimon)在批处理 OLAP 查询(大规模数据扫描 + 聚合)性能上有什么差异?Delta 和 Iceberg 的”不可变文件 + 统计信息”设计天然适合 OLAP(文件有序、无 Compaction 读放大);Hudi MoR 和 Paimon 由于存在未 Compacted 的文件,在 OLAP 查询时有额外的合并代价。在选型时,如何量化这个”实时写入能力”和”OLAP 查询性能”之间的权衡?
  3. 如果一个组织同时使用 Delta Lake(用于批处理数仓)和 Paimon(用于实时写入),存在”双格式并存”的局面。数据在 Paimon(实时更新)中写入,定期转换为 Delta Lake(供 OLAP 查询)。这个定期转换的过程(Paimon → Delta Lake)如何实现?转换过程中的数据一致性如何保证(避免读到转换中间态的不一致数据)?