流式数据湖Paimon探秘之旅 (七) 读取流程全解析

第7章:读取流程全解析

读取的三个阶段

Paimon的读取分为三个阶段:

  1. 扫描计划(Scan):确定需要读取哪些文件
  2. 分片生成(Split):将文件分割成可并行处理的任务
  3. 数据读取(Read):从分片读取实际数据

深入每个阶段

7.1 FileStoreScan扫描接口

扫描的目的

从最新的Snapshot开始,找出所有需要读取的数据文件。

java 复制代码
FileStoreScan scan = fileStore.newScan();

// 应用谓词(where条件)
scan.withFilter(predicate);

// 获得读取计划
Plan plan = scan.plan();

// Plan包含:
// - 所有需要读的文件
// - 文件的元数据(min_key, max_key等)
扫描的性能优化

1. 谓词下推(Predicate Pushdown)

sql 复制代码
SELECT * FROM users WHERE age > 30;

不优化:
  读取: 所有users记录
  过滤: 哪些age > 30
  
优化后:
  检查Manifest:
    - file1: age min=20, max=28 → skip
    - file2: age min=25, max=35 → read ✓
    - file3: age min=30, max=40 → read ✓
  结果: 只读3个文件中的2个

2. 分区裁剪(Partition Pruning)

sql 复制代码
SELECT * FROM events WHERE dt='2024-01-15';

执行:
  读分区列表 → [dt=2024-01-01, dt=2024-01-15, dt=2024-01-31]
  过滤 → [dt=2024-01-15]
  只读dt=2024-01-15目录下的文件
  
效果: 扫描文件数减少 95%

7.2 Split生成与分发

什么是Split?

Split是数据文件的可读取单位,用于分布式读取。

ini 复制代码
原始文件:data-1.parquet (1GB)
        ↓
        Split1: offset=0, length=256MB
        Split2: offset=256MB, length=256MB
        Split3: offset=512MB, length=256MB
        Split4: offset=768MB, length=256MB
        ↓
        4个Split可以并行读取
Split的分配策略
perl 复制代码
单个并行度读取:
  Task-0: 读取所有splits顺序读取
  
多个并行度读取:
  Task-0: 读取 split-0, split-4, split-8, ...
  Task-1: 读取 split-1, split-5, split-9, ...
  Task-2: 读取 split-2, split-6, split-10, ...
  Task-3: 读取 split-3, split-7, split-11, ...
  
  (轮询分配splits)

7.3 SplitRead数据读取

读取的工作流程
java 复制代码
SplitRead<T> read = fileStore.newRead();

for (Split split : splits) {
  RecordReader reader = read.createReader(split);
  
  RecordBatch batch;
  while ((batch = reader.readBatch()) != null) {
    // 处理这批记录
    for (Record record : batch) {
      process(record);
    }
  }
  
  reader.close();
}
批量读取的好处
scss 复制代码
逐记录读取(低效):
  for i in 1..1000000 {
    record = file.read()  ← 1000000次I/O调用!
    process(record)
  }

批量读取(高效):
  for batch in batches {
    batch = file.readBatch(4096)  ← 仅245次I/O调用
    for record in batch {
      process(record)
    }
  }
  
性能提升: 4096倍!

7.4 谓词下推与过滤优化

三层过滤
yaml 复制代码
层1:Manifest级别过滤
  min_key <= target_key <= max_key?
  → 快速排除大量文件
  
层2:文件级别统计过滤
  file_stats:
    age: min=25, max=35
  age > 30?
  → 排除不符合的文件
  
层3:记录级别过滤
  (age > 30)? → keep : skip
  → 最终过滤
where子句的处理
sql 复制代码
WHERE user_id = 100 AND age > 30

分解为:
  谓词1: user_id = 100 (主键谓词 → Manifest过滤)
  谓词2: age > 30 (非主键谓词 → 记录级过滤)

执行:
  1. Manifest过滤 → user_id=100的bucket
  2. 读该bucket的文件
  3. 对每条记录检查 age > 30

总结:读取流程的关键优化

1. 多层过滤链

scss 复制代码
Manifest → 分区 → 文件统计 → 记录级
(快速)     (快速)  (中等)    (精准)

2. 批量处理

css 复制代码
减少I/O次数
减少虚拟机调用开销
提升CPU缓存命中率

3. 分布式并行

复制代码
Split分配 → 并行读取 → 吞吐量线性扩展

相关代码

  • FileStoreScan:paimon-core/src/main/java/org/apache/paimon/operation/FileStoreScan.java
  • SplitRead:paimon-core/src/main/java/org/apache/paimon/io/SplitRead.java
  • Split:paimon-api/src/main/java/org/apache/paimon/table/source/Split.java
相关推荐
我是章汕呐14 小时前
政策评估的“黄金标准”:DID模型从原理到Stata实操
大数据·人工智能·经验分享·算法·回归
Data-Miner14 小时前
54页可编辑PPT | 数据中台建设方案汇报
大数据·人工智能
皮皮学姐分享-ppx15 小时前
1447上市公司数字化转型速度的计算(2000-2022年)
大数据·人工智能
才盛智能科技15 小时前
麦粒空间和元K聚合平台正式签约,全面启动流量合作
大数据·人工智能·元k聚合·麦粒空间
V搜xhliang024615 小时前
基于¹⁸F-FDG PET/CT的深度学习-影像组学-临床模型预测非小细胞肺癌脉管侵犯的价值
大数据·人工智能·python·深度学习·机器学习·机器人
juniperhan16 小时前
Flink 系列第4篇:Flink 时间系统与 Timer 定时器实战精讲
java·大数据·数据仓库·flink
2501_9481142416 小时前
Claude Sonnet 4.6 深度评测:性能逼近 Opus、成本打骨折,附接入方案与选型指南
大数据·网络·人工智能·安全·架构
RFID舜识物联网17 小时前
耐高温RFID技术如何解决汽车涂装车间管理难题?
大数据·人工智能·嵌入式硬件·物联网·安全·信息与通信
宸津-代码粉碎机17 小时前
Spring Boot 4.0 实战技巧全解析
java·大数据·spring boot·后端·python
TK云大师-KK17 小时前
2026年4月TikTok矩阵运营系统横向评测TOP5
大数据·网络·人工智能·矩阵·自动化·新媒体运营