流式数据湖Paimon探秘之旅 (六) 提交流程与事务保证

第6章:提交流程与事务保证

如何确保原子提交?

Paimon使用两阶段提交协议确保分布式写入的一致性:

scss 复制代码
阶段1:Prepare(准备)
  ├─ 验证数据(检查schema, 类型等)
  ├─ 生成临时元数据
  └─ 返回CommitMessage给用户

阶段2:Commit(提交)
  ├─ 使用分布式锁
  ├─ 冲突检测
  ├─ 原子写入Snapshot
  └─ 释放锁

提交的关键步骤

6.1 两阶段提交协议

阶段1:Prepare(数据端)

在Flink中,prepare通常发生在:

  • Checkpoint触发时
  • 应用关闭时
java 复制代码
// 写数据
write.write(record1);
write.write(record2);
write.write(record3);

// Prepare:生成元数据,但不提交
CommitMessage msg = write.prepareCommit();

msg包含:
  ├─ 生成的数据文件列表
  ├─ 文件的元数据(min_key, max_key, row_count)
  ├─ 操作类型(ADD/DELETE等)
  └─ 其他统计信息
阶段2:Commit(协调端)

Commit通常由协调器(Flink JobManager)调用:

java 复制代码
// 收集所有并行度的CommitMessages
List<CommitMessage> messages = [msg1, msg2, msg3, ...];

// 提交
commit.commit(checkpointId, messages);
为什么需要两阶段?
yaml 复制代码
单阶段提交的问题:
  Task1: 写入文件 → 立即提交 ✓
  Task2: 写入文件 → 立即提交 ✓
  Task3: 写入文件 → 提交失败 ✗
  
  结果:表中只有Task1和Task2的数据,数据丢失!

两阶段提交的优势:
  Task1: 写入文件 → 等待 (Prepare)
  Task2: 写入文件 → 等待 (Prepare)
  Task3: 写入文件 → 等待 (Prepare)
  
  协调器: 检查所有Task准备完毕 → 全部Commit
  
  如果Task3失败,Coordinator可以:
    - 回滚Task1和Task2
    - 重新启动全部Task
  
  结果:要么全部成功,要么全部失败(原子性)

6.2 FileStoreCommit提交实现

提交的步骤
markdown 复制代码
1. 获取分布式锁
   ↓
2. 检查冲突
   ├─ 读取最新Snapshot
   ├─ 比较新增文件与现有文件
   └─ 检测是否有冲突
   ↓
3. 生成新Manifest
   ├─ 合并旧Manifest + 新文件
   └─ 写入新Manifest文件
   ↓
4. 生成ManifestList
   └─ 更新清单列表
   ↓
5. 原子写入Snapshot
   └─ 写入snapshot-N文件(原子操作)
   ↓
6. 释放锁
冲突检测的原理
markdown 复制代码
情况1:无冲突(两个writer在不同bucket)
  Writer1: 写入 bucket-0 的文件
  Writer2: 写入 bucket-1 的文件
  ✓ 完全独立,无冲突

情况2:冲突(两个writer在同一bucket)
  Writer1: 写入 bucket-0 的文件A
  Writer2: 也想写入 bucket-0
  
  检测过程:
    - 读当前Snapshot → manifest-5
    - 检查bucket-0的现有文件 → [file1, file2]
    - Writer1要添加fileA → [file1, file2, fileA] ✓
    - Writer2也要添加fileB
    - 但fileA和fileB都写了user_id=100的数据
    - 冲突!✗ 需要重试或合并

6.3 Manifest文件合并

Manifest的演化
scss 复制代码
时刻1:初始状态
  snapshot-1 → manifest-1 → [file-1, file-2]

时刻2:Writer1提交
  新Manifest包含:[file-1, file-2] + [file-3] = manifest-2
  snapshot-2 → manifest-2

时刻3:Writer2提交(可能与Writer1并发)
  读最新Snapshot-2的manifest-2 → [file-1, file-2, file-3]
  新Manifest包含:[file-1, file-2, file-3] + [file-4] = manifest-3
  snapshot-3 → manifest-3
避免Manifest爆炸

多次写入会产生很多Manifest文件,需要定期合并:

css 复制代码
定期任务:CompactManifest
  
  before: manifest-1, manifest-2, manifest-3, ..., manifest-100
          (100个文件,查询时需要遍历所有)
  
  after: manifest-compact-1
         (1个合并文件,查询快速)
  
  执行命令:
  CALL compact_manifests('db', 'table');

6.4 冲突检测与乐观锁

乐观锁的思想
markdown 复制代码
假设冲突很少发生:

尝试提交:
  1. 读最新版本 (不加锁)
  2. 准备新数据
  3. 提交时加锁
  4. 验证版本未改变
  5. 写新版本
  6. 释放锁

好处:
  - 大多数写入不需要等待锁
  - 只在冲突时重试
版本号机制
java 复制代码
Snapshot {
  id: 5,                        // 快照ID
  commitIdentifier: 1673088000, // 版本号
  baseManifestList: "...",
  deltaManifestList: "..."
}

提交流程:
  预期版本:currentSnapshotId = 5
  ↓
  写入数据...
  ↓
  检查:当前仍是snapshot-5吗?
    ✓ 是 → 提交新snapshot-6
    ✗ 否 → 有其他writer已提交 → 需要重试

总结:事务保证的关键点

1. 原子性(Atomicity)

scss 复制代码
Snapshot文件的原子写入
  ↓
要么整个snapshot-N写入成功
要么完全不写(故障回滚)
  ↓
不可能出现部分更新的状态

2. 一致性(Consistency)

复制代码
冲突检测
  ↓
如果发现冲突,自动重试或失败
  ↓
确保最终结果是一致的

3. 隔离性(Isolation)

sql 复制代码
分布式锁
  ↓
Commit阶段串行化
  ↓
多个writer不会同时修改表

4. 持久性(Durability)

复制代码
文件系统的可靠性
  ↓
Snapshot一旦写入,永不丢失

相关代码

  • FileStoreCommit:paimon-core/src/main/java/org/apache/paimon/operation/FileStoreCommit.java
  • Snapshot:paimon-api/src/main/java/org/apache/paimon/Snapshot.java
  • CommitMessage:paimon-api/src/main/java/org/apache/paimon/table/sink/CommitMessage.java
相关推荐
金融小师妹7 小时前
基于多模态宏观建模与历史序列对齐:原油能源供给冲击的“类1970年代”演化路径与全球应对机制再评估
大数据·人工智能·能源
播播资源7 小时前
OpenAI2026 年 3 月 18 日最新 gpt-5.4-nano模型:AI 智能体的“神经末梢”,以极低成本驱动高频任务
大数据·人工智能·gpt
GJGCY8 小时前
中小企业财务AI工具技术评测:四大类别架构差异与选型维度
大数据·人工智能·ai·架构·财务·智能体
九河云9 小时前
云上安全运营中心(SOC)建设:从被动防御到主动狩猎
大数据·人工智能·安全·架构·数字化转型
武子康9 小时前
大数据-252 离线数仓 - Airflow + Crontab 入门实战:定时调度、DAG 编排与常见报错排查
大数据·后端·apache hive
jinanwuhuaguo9 小时前
OpenClaw、飞书、Claude Code、Codex:四维AI生态体系的深度解构与颗粒化对比分析
大数据·人工智能·学习·飞书·openclaw
Rubin智造社9 小时前
# OpenClaude命令实战|核心控制三剑客/reasoning+/verbose+/status 实操指南
大数据·人工智能
华奥系科技10 小时前
智慧经济新格局:解码社区、园区与城市一体化建设逻辑
大数据·人工智能·科技·物联网·安全
TDengine (老段)11 小时前
TDengine IDMP 组态面板 —— 画布
大数据·数据库·物联网·时序数据库·tdengine·涛思数据