把整个数据湖想象成一个拥有上千栋居民楼的大型社区,每栋楼是一张数据表,楼里的每一户是一条数据行。早期管理员(Hive)只有一本纸质台账,楼栋格局一变,就得把全楼住户翻出来重新登记一遍,慢且容易出错。而 Iceberg、Hudi、Delta Lake 三大开源表格式,就像三套现代化的“社区物业大脑”——有的擅长把每一版图纸存档(Iceberg),有的擅长用工单应对频繁的迁入迁出(Hudi),有的擅长把每一步施工写进日志(Delta Lake)。它们的共同目标,是让数据的写入、更新、回查都变得规范、可追溯、可并发。本文就用这套“小区物业”的比喻,带你搞懂三者的架构差异、适用场景和选型依据。

岗位关联

掌握三大表格式的取舍,是数据平台架构师完成湖仓选型的核心能力,直接影响批流一体、数据湖建仓的架构成败与长期运维成本。

目录
  1. 可视化演示
  2. 表格式概述
  3. ACID事务
  4. 时间旅行
  5. 增量处理
  6. 结构演进
  7. 适用场景
  8. 选型参考
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示数据湖表格式选型对比的核心机制,通过概览/流程/对比/趋势四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

数据湖表格式选型对比:表格式选 表格式选型的核心维度与评估框架 ACID事务实现差异与一致性保 核心机制可视化 数据湖表格式选型对比整体架构与关键组件

表格式概述

小区里住的人没变,变的是管理方式。假设你是这个巨型数据社区的业委会主任,最头疼的事是什么?一是住户变动太快,台账总是对不上;二是每次查旧账都得翻遍所有楼层;三是好几拨施工队同时进场,容易互相踩脚。Hive 这套老式管理,只有一层“目录指向文件”的记账逻辑,改一条数据往往要重写一个大目录,事务、历史、并发全都缺位。而表格式(Table Format)就是现代物业的“管理公约”,它不改变住户本身,只改变“如何登记、如何签收、如何审批”。

技术上,表格式位于存储层和计算引擎之间,它不替代 Parquet、ORC 这类文件存储格式,而是在文件之上加了一层组织逻辑:定义一张表包含哪些文件、当前 schema 是什么、每次提交让哪个版本生效。换句话说,文件还是那些砖块,表格式是砖块之上的施工图纸和验收流程。Iceberg、Hudi、Delta Lake 是当下最主流的三个选择,业界称之为“三强格局”。

一个表格式可以抽象成几个核心组件的组合:

打个比方,选表格式不是选“数据存在哪”,而是选“社区怎么管”。有的小区重档案、讲秩序,适合 Iceberg;有的人流量大、要随时处理迁入迁出,适合 Hudi;有的小区已经有成熟物业品牌(Databricks/Spark 生态),选 Delta 最顺手。

T=⟨S, F, M, Δ⟩\mathcal{T} = \langle \mathcal{S},\ \mathcal{F},\ \mathcal{M},\ \Delta \rangle
这个式子把表格式拆成四个零件:结构、文件、元数据、日志。
  1. 表的身份\mathcal{T} 代表一张数据表,对应小区里的一栋居民楼。
    T\mathcal{T}
  2. Schema 结构\mathcal{S} 是表结构,规定每户有哪些字段、什么类型,相当于楼栋的户型图。
    S\mathcal{S}
  3. 文件集合\mathcal{F} 是当前数据文件集合,相当于楼里实际入住的住户清单。
    F\mathcal{F}
  4. 元数据与日志\mathcal{M} 记录文件索引与快照,\Delta 记录每次提交的历史,分别对应物业的住户档案和维修登记簿。
    M, Δ\mathcal{M},\ \Delta

ACID事务

ACID 就像社区管理的基本法。原子性(Atomicity)是“要么整栋楼改造全部完成,要么一栋都不动”;一致性(Consistency)是“住户信息和实际永远对得上”;隔离性(Isolation)是“两拨装修队同时进场互不捣乱”;持久性(Durability)是“登记在册的改造,停电了也不会丢”。Hive 表时代最尴尬的就是查询读到“写到一半”的数据,因为一个目录下的文件随时可能被替换。

三大表格式都把 ACID 落地到了文件层面,但实现路径不同。Iceberg 通过“快照指针 + 清单文件”实现原子切换,读者要么看到旧快照,要么看到新快照,永远不会看到中间态。Delta Lake 的核心是一份事务日志(transaction log),每次提交追加一个原子条目,所有读操作以日志为准。Hudi 则用基于时间线的乐观并发控制,允许多个写者同时提交,冲突时通过文件的更新版本号协调。

这里用集合论描述“读到一个一致版本”:

所以 ACID 不是“有没有”的问题,而是“用什么机制保证”的问题。Iceberg 用图纸快照、Delta 用日志流水、Hudi 用时间线协调,三者的并发吞吐和冲突处理成本因此不同。

Vn=⋃f∈Cnrecords(f)\mathcal{V}_{n} = \bigcup_{f \in \mathbb{C}_{n}} \mathrm{records}(f)
第 n 个读事务看到的视图,等于第 n 次提交所覆盖文件集合中所有记录的并集。
  1. 视图定义\mathcal{V}_n 表示读到第 n 个版本的完整数据视图。
    Vn\mathcal{V}_{n}
  2. 提交集合\mathbb{C}_n 是第 n 次提交包含的数据文件集合,相当于物业验收时签收的那批施工单。
    Cn\mathbb{C}_{n}
  3. 记录并集\bigcup 表示把所有文件中的记录合并起来,records(f) 取单个文件里的全部行。
    ⋃f∈Cnrecords(f)\bigcup_{f \in \mathbb{C}_{n}} \mathrm{records}(f)

时间旅行

时间旅行就是物业的“档案回放”:想查三个月前的水电记录,不用穿越,翻当时存档的图纸就行。Iceberg 每次改动都生成一份完整的新快照,旧快照默认保留;Delta 把每次事务写进日志,按版本号可以还原任意历史时刻;Hudi 的时间线(timeline)也记录了每次 commit,支持按 instant 时间点回溯。三类系统都能“回到过去”,只是保留策略和清理机制不一样。

这对数据修复、审计合规和机器学习特征回填特别重要。业务上经常出现:昨天跑批的脚本写坏了数据,需要快速回滚到昨天之前的状态。Iceberg 允许执行 expire_snapshots 手动清理旧快照;Delta 用 VERSION AS OF 或 TIMESTAMP AS OF 语法读取历史版本;Hudi 则通过时间线保留 commit 记录,并配合文件版本管理实现回滚。

时间旅行查询的本质可以写成:

档案能回放,代价是旧档案占仓库。所以时间旅行不是免费的:保留的快照越多,存储成本越高。选用时要评估历史保留窗口,避免无限制堆快照。

Read(t)=Vs∗,s∗=arg⁡max⁡s∈Ssnap{ time(s)≤t }\mathrm{Read}(t) = \mathcal{V}_{s^*}, \quad s^* = \arg\max_{s \in \mathcal{S}_{\mathrm{snap}}} \{\, \mathrm{time}(s) \le t \,\}
查询某个历史时刻 t 的数据,就是找到“时间不晚于 t 的最新那个快照”。
  1. 读取历史\mathrm{Read}(t) 表示在时刻 t 发起的数据读取请求。
    Read(t)\mathrm{Read}(t)
  2. 候选快照\mathcal{S}_{\mathrm{snap}} 是所有已提交快照的集合,对应物业档案馆里的全部图纸版本。
    Ssnap\mathcal{S}_{\mathrm{snap}}
  3. 取最大时刻\arg\max 表示在满足 time(s) ≤ t 的快照中,挑出时间戳最大的那个,也就是离 t 最近但不超过 t 的版本。
    s∗=arg⁡max⁡s∈Ssnap{ time(s)≤t }s^* = \arg\max_{s \in \mathcal{S}_{\mathrm{snap}}} \{\, \mathrm{time}(s) \le t \,\}

增量处理

Hudi 的物业风格是“小修小补记工单”:平时换灯泡、通水管这类小事,先在工单本上记一笔,住户查询时看到的是“基础档案 + 未处理工单”的合并结果;等工单攒多了,物业再集中做大整改,把工单合并进基础档案。这个模式在 Hudi 里叫 MOR(Merge On Read,读时合并),写入只追加 log,更新开销小,但查询时要合并 log,读放大。

Iceberg 和 Delta 更偏爱“一次性大装修”:每次更新把涉及的旧文件重写一份新的,再原子切换指针,这叫 COW(Copy On Write,写时复制)。COW 的好处是读取路径干净,查询永远只读最终文件;坏处是写放大明显,更新一条记录可能重写整个文件。upsert(更新或插入)是高频业务的核心需求:订单状态流转、用户画像更新、特征实时修正,都依赖高效的 upsert。

两种模式的代价可以直观对比:

所以实时更新需求量大的场景,Hudi 的“工单制”优势明显;但如果你更在意查询性能和简洁的读路径,Iceberg 或 Delta 的“大装修”思路更合适。

WriteAmplificationMOR=O(1),ReadCostMOR=O(1+∣L∣)\text{WriteAmplification}_{\text{MOR}} = O(1), \quad \text{ReadCost}_{\text{MOR}} = O(1 + |\mathcal{L}|)
MOR 写代价恒定,但读代价会随 log 文件数量增长而增长,这就是“写快读慢”的本质。
  1. 写放大WriteAmplification 指一次逻辑更新实际触发多少文件写入,MOR 只需追加日志,故为 O(1)。
    WriteAmplificationMOR=O(1)\text{WriteAmplification}_{\text{MOR}} = O(1)
  2. 读成本ReadCost 是查询一次最新视图的代价,等于读基础文件加上合并所有 log。
    ReadCostMOR\text{ReadCost}_{\text{MOR}}
  3. 日志集合规模|\mathcal{L}| 是待合并的 log 文件数量,log 越多,读得越慢,这也是 Hudi 定期做 compaction 的原因。
    O(1+∣L∣)O(1 + |\mathcal{L}|)

结构演进

业务一变,户型就得改。老式管理想加一间房,得把整栋楼推倒重建;新的社区管理系统支持“直接加堵墙、换个门牌”,而且不影响其他住户。在数据表里,这就是 schema evolution(结构演进):新增列、删除列、重命名列、调整字段类型,而不必重写底层全部数据文件。

Iceberg 通过独立的 schema 版本和字段 ID 映射实现演进:每个字段有唯一 ID,写入新列只是追加文件,旧文件用 ID 对应到新 schema,读取时自动填充默认值。Delta 把 schema 变更也写进事务日志,Spark 能自动识别新旧结构。Hudi 则依赖 schema registry(如 Confluent Schema Registry)或用户自管 schema,演进时需保证兼容性。类型提升(如 int 扩展为 long)普遍支持,类型降级(如 long 变 int)通常被禁止,因为可能丢精度。

新结构读老数据,本质是对旧数据做投影:

选表格式之前,想想团队改表的频率:如果业务字段经常变动,Iceberg 的字段 ID 映射最省心;如果主要在 Spark 里开发,Delta 与 Spark 的 schema 管理集成最顺滑。

Vnew=ΠC1,C2,…,Cn(Vold)\mathcal{V}_{\mathrm{new}} = \Pi_{C_1, C_2, \dots, C_n}(\mathcal{V}_{\mathrm{old}})
新 schema 读旧数据,只是从旧视图中选出需要的列,而不是改旧文件。
  1. 新视图\mathcal{V}_{\mathrm{new}} 是应用新 schema 后对数据的读取结果。
    Vnew\mathcal{V}_{\mathrm{new}}
  2. 投影算子\Pi 是关系代数里的投影操作,表示只保留列 C_1 到 C_n,如只取户主姓名和门牌号。
    ΠC1,C2,…,Cn\Pi_{C_1, C_2, \dots, C_n}
  3. 旧视图\mathcal{V}_{\mathrm{old}} 是底层数据原本存储时对应的旧结构视图。
    Vold\mathcal{V}_{\mathrm{old}}

适用场景

不同小区有不同的脾气。科技园区追求实时人流管理,适合 Hudi;历史档案馆注重精确保存与回溯,适合 Iceberg;写字楼用连锁物业品牌统一管理,适合 Delta Lake + Spark。把场景匹配到表格式,是选型的真正核心。

批流一体是当前最热的场景:上游 Kafka 实时产生数据,下游既要跑流计算,又要跑批量 ETL。Hudi 的 MOR 天然适合流式 upsert,数据一到就写 log,查询端合并读取。Iceberg 在 Flink 生态中支持流式读取快照,能稳定感知新提交。Delta 的 Change Data Feed 则把变更记录显式暴露出来,方便下游增量消费。数据湖建仓场景中,三者都能提供 ACID 和 SQL 分析能力,但 Iceberg 在查询引擎兼容性上更广(Spark、Flink、Trino、Presto 均可),Delta 在 Databricks 平台上体验最佳。机器学习特征平台则需要时间旅行做历史回填,Hudi 做在线增量特征,“一个湖里多种表格式混用”正在成为常态。

选型可以建模成一个带约束的优化问题:

所以选型第一步不是问“哪个最好”,而是问“我的小区是哪种类型”:更新有多频繁?查询有多重?计算引擎到底是什么?

min⁡F(w1⋅Latency+w2⋅ComputeCost)s.t.ACID≥1, Throughput≥θ\min_{\mathrm{F}} \left( w_1 \cdot \mathrm{Latency} + w_2 \cdot \mathrm{ComputeCost} \right) \quad \text{s.t.} \quad \mathrm{ACID} \ge 1,\ \mathrm{Throughput} \ge \theta
在满足事务和吞吐底线的前提下,追求更低的延迟与计算成本。
  1. 最小化目标\min 表示我们要优化的总代价,包含延迟 Latency 和计算成本 ComputeCost。
    min⁡F(w1⋅Latency+w2⋅ComputeCost)\min_{\mathrm{F}} \left( w_1 \cdot \mathrm{Latency} + w_2 \cdot \mathrm{ComputeCost} \right)
  2. 权重w_1、w_2 代表不同业务对延迟和成本的敏感程度,实时业务给延迟更高权重。
    w1, w2w_1,\ w_2
  3. 约束条件s.t. 后面是硬性底线,ACID 至少为 1(必须有事务能力),吞吐必须不低于阈值 θ。
    ACID≥1, Throughput≥θ\mathrm{ACID} \ge 1,\ \mathrm{Throughput} \ge \theta

选型参考

最后是拍板环节。就像物业公司竞标,评委手里有一张评分表:服务响应速度(实时性)、档案完整度(事务与回溯)、系统兼容度(生态)、维护费用(运维成本)。加权打分,总分最高者中标。

关键技术维度整理成四块:第一,数据更新模式——高频点更新选 Hudi MOR,低频大批量覆盖选 Iceberg COW,Spark 强绑定场景选 Delta;第二,生态成熟度——Iceberg 是 Apache 顶级项目,Spark、Flink、Trino 兼容最广;Delta 已捐给 Linux Foundation,但深度优化在 Databricks;Hudi 在增量和湖仓场景社区活跃;第三,云厂商支持——AWS S3 Tables 原生支持 Iceberg,阿里云 EMR 对 Iceberg 和 Hudi 都有托管支持,Azure Synapse 对 Delta 支持最成熟;第四,迁移成本——从 Hive 迁移要考虑表的重建、分区对齐、历史快照保留,以及小文件治理的额外工作量。

把上面的维度写成加权评分模型:

没有“最好”的表格式,只有“最合适”的组合。建议把评分表变成一张真实的 POC 清单,用业务数据在三种引擎上各跑一遍,测延迟、测吞吐、测迁移成本,再拍板。

S(F)=∑i=14wi⋅qi(F),F∈{Iceberg,Hudi,Delta Lake}S(F) = \sum_{i=1}^{4} w_i \cdot q_i(F), \quad F \in \{\text{Iceberg}, \text{Hudi}, \text{Delta Lake}\}
四种表格式的总分,等于四个维度得分按权重加权求和。
  1. 总分S(F) 是表格式 F 的最终选型得分。
    S(F)S(F)
  2. 求和\sum_{i=1}^{4} 表示把四个维度的得分全部加起来。
    ∑i=14\sum_{i=1}^{4}
  3. 权重与得分w_i 是第 i 个维度的权重,q_i(F) 是表格式 F 在该维度的得分,权重越高说明该项越重要。
    wi⋅qi(F)w_i \cdot q_i(F)

AI 应用场景

湖仓一体实时数仓选型

阶段:数据接入与存储选型

解决的问题:传统数仓难以低成本存储半结构化数据,且对高并发更新支持差。AI 方案采用“一湖多格式”:用 Hudi MOR 承接 Kafka 实时订单流,支持高频状态更新;用 Iceberg 承载清洗后的明细宽表,提供稳定的批量查询与时间旅行。

具体案例:某电商平台将订单状态流(created→paid→shipped→completed)写入 Hudi 表,每笔订单平均更新 3-5 次,MOR 模式让更新延迟低于 1 分钟;同时用 Iceberg 同步宽表供 BI 查询,P95 查询耗时从 8 秒降到 1.2 秒。

历史数据湖迁移与数据修复

阶段:数据治理与存储优化

解决的问题:Hive 表缺少事务和版本管理,数据写坏后只能重跑全量任务。迁移到 Iceberg 后,利用快照隔离和时间旅行机制,可以精确定位异常提交并回滚。

具体案例:某金融机构的每日对账数据频繁出现脏写,迁移到 Iceberg 后,运维人员通过 TIMESTAMP AS OF 定位到 T-2 的错误快照并回滚,修复时间从 8 小时缩短到 10 分钟,审计报告也能直接引用快照版本号。

Python 演示

python69 行
from copy import deepcopy  class VersionedTable:    def __init__(self, name):        self.name = name        self.commits = []     def append_commit(self, rows):        self.commits.append(deepcopy(rows))        return len(self.commits) - 1  class IcebergLike(VersionedTable):    def write_snapshot(self, rows):        return self.append_commit(rows)     def read(self, version=None):        if version is None:            version = len(self.commits) - 1        return self.commits[version]  class HudiLike(VersionedTable):    def __init__(self, name):        super().__init__(name)        self.base = []        self.log = []     def upsert(self, key, row):        self.log.append((key, row))     def merge_on_read(self):        merged = {r["id"]: deepcopy(r) for r in self.base}        for key, row in self.log:            merged[key] = deepcopy(row)        return list(merged.values())     def compact(self):        self.base = self.merge_on_read()        self.log = []        self.append_commit(deepcopy(self.base))  class DeltaLike(VersionedTable):    def write_with_log(self, rows):        return self.append_commit(rows)  def main():    v1 = [{"id": 1, "v": "a"}, {"id": 2, "v": "b"}]     iceberg = IcebergLike("iceberg")    v_old = iceberg.write_snapshot(v1)    v2 = [{"id": 1, "v": "a2"}, {"id": 2, "v": "b"}]    iceberg.write_snapshot(v2)    print("iceberg time travel:", iceberg.read(v_old))    print("iceberg latest:", iceberg.read())     hudi = HudiLike("hudi")    hudi.base = deepcopy(v1)    hudi.upsert(1, {"id": 1, "v": "a2"})    print("hudi mor view:", hudi.merge_on_read())    hudi.compact()    print("hudi after compact:", hudi.base)  if __name__ == "__main__":    main()
目的:用纯 Python 模拟三大表格式的核心行为——Iceberg 的不可变快照与时间旅行、Hudi 的 log 写入与读时合并。
  1. self.commits.append(deepcopy(rows))用深拷贝模拟“文件快照不可变”,后续写入不会污染旧版本。
  2. iceberg.write_snapshot(v2)每次写入生成新快照,旧快照仍留在 commits 列表里,实现时间旅行。
  3. iceberg.read(v_old)按版本号读取历史数据,对应 Iceberg 的 snapshot 指针切换。
  4. hudi.upsert(1, {...})更新只追加到 log 列表,不触碰 base,对应 MOR 的低写放大。
  5. hudi.merge_on_read()把 base 和 log 合并成最新视图,对应 MOR 的读时合并逻辑。
  6. hudi.compact()把 log 合并进 base 并清空日志,对应 Hudi 的 compaction 操作。

常见误区

误区很多初学者以为 Iceberg 像 Parquet 一样是存数据的文件格式,甚至问“数据转成 Iceberg 需要多少存储空间”。

正解Iceberg 是表格式,是元数据管理层,实际数据文件仍然是 Parquet、ORC 等。它管理的是“哪些文件属于这张表、当前快照指向哪批文件”,就像物业系统管理楼盘,不代表要把楼拆了重盖。

为何常见:名字里带“格式”二字,且表格式会生成 manifest 等新文件类型,容易让人误以为是底层存储格式。

误区看到 Delta Lake 的教程总跟 Databricks 绑定,以为它是商业闭源组件,开源社区用不了。

正解Delta Lake 协议已开源并捐赠给 Linux Foundation,开源 Spark 可以直接读写 Delta 表。Databricks 只是提供了额外的商业优化与托管服

为何常见:官方宣传材料多围绕 Databricks 平台展开,给人“闭源商业产品”的错觉。

误区MOR 每次查询要合并 base 和 log,有人直接断定 Hudi 读路径慢,不能用于报表分析。

正解Hudi 提供多种查询模式,包括只读 base file 的 read-optimized 模式,以及通过 clustering 重写合并 log 后的净化文件。实际读性能可通过表服务调优,并非绝对短板。

为何常见:把“写优读劣”的 trade-off 理解为不可修复的缺陷,忽略了 Hudi 的 compaction 和 clustering 机制。

误区认为选型就像锁定婚约,整个湖定了 Iceberg 就不能再用 Hudi 或 Delta。

正解现实中“一湖多格式”很常见,不同表按业务特征分别选择表格式,甚至用同步工具把 Hudi 表实时同步成 Iceberg 表供分析查询。

为何常见:技术选型文章习惯做“三选一”对比,忽略了混合架构在真实企业中的普遍性。

误区以为 Iceberg/Hudi/Delta 会自动优化小文件,从此不用再关心文件数量。

正解表格式只提供 compaction、rewrite 等治理工具,但需要定时触发或配合调度任务执行。如果不做治理,小文件照样拖慢查询和元数据操作。

为何常见:把“支持压缩”等同于“自动压缩”,混淆了能力与默认行为。

面试题

Q1. 以下哪一组是三大开源数据湖表格式?

单选题 · easy

  • A.Parquet、ORC、Avro 文件格式
  • B.Iceberg、Hudi、Delta Lake← 正确答案
  • C.HDFS、S3、OSS 存储系统
  • D.Kafka、Flink、Spark 计算框架

答案:B。Parquet/ORC 是文件存储格式,Kafka/Flink/Spark 是计算与传输组件,而三大开源表格式是 Iceberg、Hudi 与 Delta Lake。

Q2. 表格式在数据湖架构中位于哪一层?

单选题 · easy

  • A.存储层与计算引擎之间的管理层← 正确答案
  • B.网络传输与协议连接层
  • C.应用展示与报表服务层
  • D.操作系统内核调度层

答案:A。表格式管理数据文件的组织、提交和读取语义,是存储层与计算引擎之间的管理层,类似物业系统管小区但不替代小区本身。

Q3. Iceberg 实现时间旅行主要依赖什么机制?

单选题 · mid

  • A.纯事务日志回放机制
  • B.快照指针与清单文件← 正确答案
  • C.数据库行级触发器
  • D.内存缓存加速机制

答案:B。Iceberg 每次提交生成新的 manifest list 并切换快照指针,旧快照文件仍保留,所以能按快照号读取任意历史版本。

Q4. Hudi MOR 模式下的读取路径是什么?

单选题 · mid

  • A.只读取基础 base 文件
  • B.合并 base 文件与增量日志← 正确答案
  • C.读取全部历史版本再合并
  • D.直接扫描 Parquet 数据文件

答案:B。MOR 读时要把 base 文件和 log 里的增量记录合并成最新视图;log 越长合并开销越大,所以需要定期 compaction。

Q5. 以下哪些是三大表格式普遍提供的核心能力?

多选题 · mid

  • A.提供 ACID 事务保证← 正确答案
  • B.支持时间旅行与回溯← 正确答案
  • C.支持 Schema 演进管理← 正确答案
  • D.自动购买云计算资源

答案:ABC。ACID、时间旅行、Schema 演进是三大表格式的共同卖点;自动购买云资源不属于表格式职责,选 D 的同学把选型和计费搞混了。

Q6. 哪种表格式以“事务日志”作为 ACID 的核心载体?

单选题 · mid

  • A.Iceberg 快照指针机制
  • B.Hudi 增量时间线机制
  • C.Delta Lake 事务日志机制← 正确答案
  • D.Hadoop 分布式文件机制

答案:C。Delta Lake 每次事务先追加日志再生效,日志是原子性、隔离性的根本依据,类似施工前先签字再动工。

Q7. 关于 Iceberg 架构,以下说法正确的有哪些?

多选题 · hard

  • A.数据文件仍使用 Parquet 存储← 正确答案
  • B.元数据含清单与快照指针← 正确答案
  • C.每次写入重写全表文件
  • D.支持隐藏分区自动演进← 正确答案

答案:ABD。Iceberg 是表格式,底层文件可继续用 Parquet;它只重写受影响文件而非全表;隐藏分区让分区演进自动化。C 是典型误解。

Q8. 高频小批实时更新场景,优先考虑哪种表格式?

单选题 · easy

  • A.Hudi 的 MOR 增量引擎← 正确答案
  • B.Iceberg 的 COW 快照引擎
  • C.Delta 的全表扫描方案
  • D.Hive 的 ORC 存储方案

答案:A。Hudi MOR 每次更新只写 log,写代价低,适合高频点更新;COW 和全表扫描更新代价高,不适合实时小批写入。

Q9. 做数据湖表格式选型时,应重点评估哪些因素?

多选题 · hard

  • A.实时 upsert 与查询需求← 正确答案
  • B.Spark 与 Flink 技术占比← 正确答案
  • C.云厂商托管支持程度← 正确答案
  • D.公司品牌视觉主色

答案:ABC。更新模式、计算引擎生态和云厂商托管能力直接决定落地效果;公司 Logo 颜色不影响表格式性能,选 D 属于卖萌。

Q10. 在 Iceberg 中执行 expire_snapshots 的主要目的是什么?

单选题 · hard

  • A.删除全部历史数据快照
  • B.清理过期快照释放存储← 正确答案
  • C.将数据转换为 Hudi 格式
  • D.创建新的元数据 Schema

答案:B。expire_snapshots 用于清理超过保留期限的旧快照,释放存储空间;它不删除最新数据,也不做格式转换或 Schema 变更。