Paimon的First-row(首行保留)合并引擎?
在 Apache Paimon 的官方文档中,First-row(首行保留) 是一种专门针对特定流式去重场景设计的合并引擎(Merge Engine)。
以下为您详细梳理 First-row 合并引擎的核心概念、工作机制、约束限制、性能保障以及配置示例。
一、 什么是 First-row 合并引擎?
在主键表(Primary Key Table)中,当 Paimon 写入相同主键的多条记录时,需要决定如何进行合并。
- 默认的 Deduplicate(去重) 引擎会保留主键相同的最新一条(最后一行)数据。
- First-row(首行保留) 引擎则相反,它会保留相同主键的第一条(最早一行)数据,并自动丢弃后续写入的具有相同主键的所有记录。
典型应用场景:
这在流式计算中非常适合替代传统的日志去重(Log Deduplication)。例如,需要记录用户的“首次登录时间”、“首次付费行为”、“广告的首次点击事件”等,这类业务只关心主键第一次出现的快照,后续的更新数据无需处理。
二、 核心机制与特点
1. 仅生成 Insert-only Changelog(纯插入变更日志)
由于 First-row 引擎一旦确定了第一行数据后,后续的数据一律被忽略,因此该表的数据永远不会发生更新(Update)或删除(Delete)。
这使得 First-row 引擎在向下游发送 Changelog 时,只会产生 +I(Insert)消息,而不会产生 -U / +U(Update)或 -D(Delete)消息。这极大地降低了下游流处理引擎的处理负担,比默认的 Deduplicate 引擎具有更高的传输与计算效率。
2. 独特的 Data Visibility(数据可见性保证)
由于新数据写入时,需要确定该主键在之前的历史文件中是否存在:
- 可见性约束:First-row 引擎的表,Level 0 的文件只有在 Compact(合并)到高层之后,其中的数据对查询才可见。
- 延迟影响:Paimon 默认的 Compaction 是同步的。如果用户开启了异步 Compaction,由于 Level 0 文件未及时合并,可能会导致查询时出现短暂的数据可见性延迟。
3. 激进的 Lookup Compaction 策略
为了能够快速判断新写入的主键是否是“首次出现”,Paimon 在后台会采用一种更为积极的 Lookup Compaction 策略:
- 每当触发 Compaction 时,Paimon 会强制将 Level 0 的文件合并到更高的层级。
- 相关的优化参数:
'lookup-compact':设置 Lookup Compaction 的模式。radical(默认):使用非常积极的ForceUpLevel0Compaction策略,强制提升合并速度。gentle:使用较为温和的通用合并策略(UniversalCompaction)。
三、 约束与限制
由于 First-row 引擎的设计目标是“只保留第一行且不作物理更新”,因此它在使用上存在以下严格的限制条件:
- 不支持 Sequence Field:不能指定
'sequence.field'(因为首行是由写入的先后顺序天然决定的,无法也无需通过版本字段去比对大小)。 - 不支持 DELETE 和 UPDATE_BEFORE 消息:
- 默认情况下,该引擎不接受
DELETE和UPDATE_BEFORE类型的变更消息。 - 如果上游不可避免地引入了这两种消息,必须显式配置
'ignore-delete' = 'true'来忽略它们。
- 默认情况下,该引擎不接受
- Changelog Producer 限制:
- First-row 引擎仅支持
none和lookup两种 Changelog 产生模式。 - 如果需要进行流式读取(Streaming Queries),则必须配置
'changelog-producer' = 'lookup'。
- First-row 引擎仅支持
四、 DDL 配置示例(Flink SQL)
在 Flink SQL 中创建一个使用 First-row 合并引擎的 Paimon 主键表示例如下:
CREATE TABLE user_first_behavior (
user_id BIGINT,
action_time TIMESTAMP(3),
action STRING,
PRIMARY KEY (user_id) NOT ENFORCED
) WITH (
'merge-engine' = 'first-row', -- 指定合并引擎为 first-row
'changelog-producer' = 'lookup', -- 若需要流式读取,此项为必填项
'ignore-delete' = 'true', -- 忽略可能存在的删除或更新前置消息
'lookup-compact' = 'radical' -- 采用激进的Level 0合并策略以保证可见性(可选)
);
总结
First-row(首行保留)是 Paimon 主键表的一项高效去重方案。它的最大优势是通过在存储层进行“首行判定”,从而向下游直接输出纯追加(Insert-only)的变更流,省去了传统流计算中庞大的状态撤回逻辑。但在使用时,需注意其对 DELETE 消息的限制以及由于依赖后台 Compaction 带来的数据可见性机制。