Hudi 是什么
Apache Hudi 是建在 HDFS 或对象存储上的表格式与写入框架,重点解决「按主键频繁更新」这件事。它提供两类表:COW(写时复制)每次写入重写受影响的 base file,读取只要读文件,写放大比较明显;MOR(读时合并)把更新先写进 delta log,查询时再把 log 与 base file 合并,写入快但读侧要付合并成本。所有提交都记录在时间线上,因此天然支持按提交时刻做增量拉取。
基本信息
| 适用平台 | Apache Hudi(Spark 与 Flink 写入,Hive、Trino 等可读) |
|---|---|
| 表类型 | COPY_ON_WRITE(写时复制)、MERGE_ON_READ(读时合并) |
| 三个关键字段 | recordkey 唯一键、precombine 版本列、partitionpath 分区路径 |
| 写入操作 | insert、upsert、bulk_insert、delete |
| 时间线 | commit、deltacommit、compaction、clean 等 instant 记录 |
| 增量读 | 按起止 instant time 读取区间内的变更 |
| 索引类型 | 默认 Bloom 索引,可替换为 Simple、HBase 等 |
| 文件管理 | clean 清理历史版本,compaction 合并 MOR 的日志文件 |
典型使用场景
- 维表、状态表这类读多写少的数据用 COW,读路径没有合并开销
- CDC 或前一日数据回流的近实时链路用 MOR,写入吞吐优先,靠 compaction 定期收拾日志
- 订单、账户等需要按主键 upsert 并保留最新状态的明细表
- 下游要按提交时刻增量拉取(只消费新到的变更)时用 incremental query,代替全表扫描
- 需要行级删除且要保留时间线可追溯的场景,用写入操作 delete 加 clean 策略管理历史版本
建表与关键参数
建表与关键参数
CREATE TABLE ods_order_binlog (
order_id STRING, -- 主键:同键按 precombine 去重
order_status STRING,
pay_amt DECIMAL(18,2),
update_time STRING, -- 版本列:保留该值最大的一行
dt STRING -- 分区路径字段
) USING hudi
TBLPROPERTIES (
'primaryKey' = 'order_id',
'preCombineField' = 'update_time',
'type' = 'MERGE_ON_READ', -- 高频写入用 MOR,读多写少改 COPY_ON_WRITE
'hoodie.cleaner.policy' = 'KEEP_LATEST_COMMITS',
'hoodie.compact.inline' = 'true' -- 写入时顺带做 compaction,抑制日志堆积
)
PARTITIONED BY (dt);两类表逐项对照
| 维度 | COW 写时复制 | MOR 读时合并 |
|---|---|---|
| 写入行为 | 重写受影响的 base file | 追加到 delta log |
| 写放大 | 高 | 低 |
| 查询路径 | 直接读 base file | base file 与 log 合并 |
| 适用场景 | 读多写少、维表 | 写多读少、CDC 近实时 |
| 额外运维 | 文件清理 | compaction 与清理都要盯 |
precombine 字段决定同一主键多行保留哪一条,规则是取该字段值最大的记录。它必须是可比字段,时间格式要统一,否则会出现旧数据覆盖新数据。
MOR 表如果长期不做 compaction,delta log 会持续堆积,同一分区查询延迟逐步升高,最后不得不停机集中合并。