数据湖湖仓一体大数据【免费下载链接】icebergApache Iceberg项目地址https://gitcode.com/gh_mirrors/iceberg5/iceberg点击查看免费下载本文基于 Apache Iceberg 官方术语表site/docs/terms.md逐一解释 Iceberg 元数据体系中的六个核心概念Snapshot快照、Manifest list清单列表、Manifest file清单文件、Partition spec分区规范、Partition tuple分区元组与Snapshot log快照日志并对照格式规范 format/spec.md 与 Java 参考实现源码说明这些概念在表元数据 JSON 和 manifest 文件中的具体存储位置与作用机制。读完本文后你将能够看懂 Iceberg 元数据层级的完整结构理解 scan planning扫描规划如何利用这些元数据做文件裁剪并能在表元数据 JSON 中定位每个术语对应的字段。上图为 Iceberg 的元数据层级结构源自 site/docs/assets/images/iceberg-metadata.pngCatalog 中的表条目持有指向当前 metadata file 的指针metadata file 中内嵌所有有效快照s0、s1每个快照指向一个 manifest listmanifest list 再指向若干 manifest filemanifest file 最终列出快照中包含的全部数据文件。本文的六个术语恰好覆盖了这条链路上每一层的关键角色。Snapshot某一时刻的表状态官方定义一个 snapshot快照是表在某个时刻的状态。每个快照列出构成该时刻表内容的全部数据文件这些数据文件分布在多个 manifest file 中而某个快照的全部 manifest 则被记录在一个唯一的 manifest list 文件中。规范对快照字段的完整定义见 format/spec.md 的### Snapshots章节版本字段说明v1/v2 必填snapshot-id唯一 long ID可选parent-snapshot-id父快照 ID无父快照时省略v2 必填sequence-number单调递增的 long标记表变更顺序v1/v2 必填timestamp-ms快照创建时间戳用于垃圾回收与表检查v2 必填manifest-list该快照的 manifest list 位置v1 中可选存在时manifests必须省略v1 可选manifestsmanifest 文件位置列表v2 已由 manifest-list 取代v2 必填summary字符串 map总结快照变更必含operation字段可选schema-id快照创建时表的当前 schema IDsummary中的operation字段取值为append仅新增数据文件、replace增删文件但表数据逻辑不变如 compaction、格式转换、overwrite逻辑覆盖、delete删除数据快照过期等操作会依据该字段跳过特定快照。在 Java 参考实现中快照由接口 api/src/main/java/org/apache/iceberg/Snapshot.java 描述关键访问器与上表一一对应sequenceNumber()、snapshotId()、parentId()、timestampMillis()、summary()、manifestListLocation()。可以确认manifestListLocation()正是术语表中快照的 manifests 列在单一 manifest list 文件中这一说法在代码层面的落点——v2 表读取快照时即从此位置出发读取 manifest 清单。规范还解释了为什么一个快照的数据文件可以存放在多个 manifest 中快速追加fast append追加数据时只需写入一个全新 manifest而不是改写已有 manifest最小化写入量多分区规范共存一个 manifest 只对应单一 partition spec表的分区配置演化后旧文件留在旧 manifest、新文件写入新 manifest而查询无需变化因为分区过滤器始终由数据列谓词推导并行规划大表拆分到多个 manifest实现可以并行规划作业、降低单个 manifest 重写成本。Manifest list快照的 manifest 索引官方定义manifest list 是列出构成某个表快照的所有 manifest 的元数据文件。清单列表中的每个 manifest 都附带描述其内容的信息如分区值范围用于加速元数据操作。规范#### Manifest Lists章节补充了关键机制每次提交快照的尝试都会写一份新的 manifest list因为产生新快照时 manifest 列表必然变化写入时清单中所有新 manifest 会记录该快照的乐观序号。此外manifest list 携带概要元数据可在规划表扫描时避免读取快照内的全部 manifest——包括新增/保留/删除的文件数以及写入该 manifest 所用的每个分区字段的取值概要field_summarycontains_null、contains_nan、lower_bound、upper_bound。docs/docs/performance.md 的 Metadata filtering 一节从使用角度印证了这一点manifest list 充当 manifest 文件的索引Iceberg 先用清单中记录的分区值范围过滤 manifest再读取被选中的 manifest 获取数据文件这使得单节点规划多 PB 级大表成为可能。Manifest file快照数据文件的清单官方定义manifest file 是列出构成快照的一子集数据文件的元数据文件。清单中的每个数据文件都随附一个 partition tuple分区元组、列级统计信息以及用于在 scan planning 中裁剪 split 的概要信息。规范### Manifests章节给出了完整细节值得完整了解manifest 是不可变的 Avro 文件本身是合法的 Iceberg 数据文件使用合法的 Iceberg 格式、schema 和列投影一个 manifest 只存放数据文件或只存放删除文件二者不能混放因为含删除文件的 manifest 在作业规划时会被优先扫描content属性记录data或deletes一个 manifest 只对应单一 partition specspec 变更时旧文件保留在旧 manifest新文件写入新 manifest——因为 manifest 文件的 schema 由分区 spec 决定manifest 的 Avro key-value metadata 中必须写入schema/schema-id、partition-spec/partition-spec-id、format-versionv2 还必填content。manifest_entry与data_file的核心字段节选自规范字段表字段类型说明0 statusint0: EXISTING、1: ADDED、2: DELETED跟踪文件增删1 snapshot_idlong文件被加入或删除的快照 IDnull 时从 manifest list 继承3 sequence_number/4 file_sequence_numberv2long数据序号 / 文件序号用于规划删除文件适用于哪些数据文件2 data_filestruct文件路径、partition tuple、指标metrics等data_file中的列级统计column_sizes、value_counts、null_value_counts、nan_value_counts、distinct_counts、lower_bounds、upper_bounds正是术语表中列级统计的具体所指它们支持在规划阶段按列过滤文件split_offsets如 Parquet 的所有 row group 偏移则直接服务于 split 裁剪。规范#### Scan Planning描述了规划流程先按 manifest 中的分区值范围与文件计数跳过无匹配文件的 manifest再把扫描谓词通过**包含式投影inclusive projection**转换为分区谓词结合列级上下界选出实际要读的文件——docs/docs/performance.md 的 Data filtering 一节以同样的口径描述了这条链路。Partition spec如何对数据分区官方定义partition spec 描述表中的数据如何分区。一个 spec 由源列 转换transform的列表组成transform 从源值生成分区值——例如date(ts)从名为ts的时间戳列生成日期分区值。规范### Partitioning章节说明每个分区字段由四部分组成源列 ID、分区字段 ID在 spec 内唯一v2 表元数据中全局唯一、transform、分区名。transform 支持identity、bucket[N]Murmur3 x86 32 位哈希取模、truncate[W]、year/month/day/hour、void且所有 transform 对 null 输入必须返回 null。规范中一段关键表述解释了 spec 的设计意图分区 spec 捕获从表数据到分区值的转换这既用于转换数据值也用于把列谓词转换为分区谓词从而将逻辑查询与物理存储解耦——分区布局可以随数据量变化而演化正确的分区过滤器始终从列谓词推导得出用户无需同时提供逻辑谓词和分区谓词。docs/docs/partitioning.md 的 Icebergs hidden partitioning 一节正是这一思想的展开Iceberg 负责把event_time转成分区值如date(event_time)生产者与消费者都不需要看见显式的分区列工作查询不再绑定表的物理布局。在源码中分区规范由 api/src/main/java/org/apache/iceberg/PartitionSpec.java 建模specId()返回规范 ID与 manifest list 中partition_spec_id字段规范要求该 ID 必须列于表元数据的partition-specs中对应。Partition tuple随每个数据文件存储的分区值官方定义partition tuple分区元组是随每个数据文件存储的分区数据元组tuple/struct。数据文件中所有行的分区元组取值相同元组由分区 spec 对行数据转换而来。术语表还特别对比Iceberg 原样unmodified存储分区值不像 Hive 表那样在文件系统路径与键之间来回做字符串转换。规范### Partitioning开头一段明确了其用途数据文件在 manifest 中随一个分区值 tuple 存储扫描时用它过滤不可能包含匹配记录的文件同一 manifest 中数据文件可来自任意分区只要分区 spec 相同。同时规范指出partitionstruct 的 schema 由写入该 manifest 的分区 spec 推导v2 中 partition struct 的字段 ID 必须与分区 spec 的分区字段 ID 一致——这解释了为什么分区演化时必须复用既有字段 ID分区字段 ID 会作为 manifest 文件中 partition tuple 的字段 ID 被持久化。docs/docs/partitioning.md 的 Problems with Hive partitioning 一节列出了 Hive 式显式分区的三类问题写入方需手工给出分区值且无法校验、查询必须手写额外过滤、查询与物理布局耦合而术语表中Iceberg 原样存储分区值这一句正是对上述问题的回应值不做字符串化转换也就不存在2018-12-01与20181201这类静默错误的格式陷阱。在 Java 实现中分区元组由 core/src/main/java/org/apache/iceberg/PartitionData.java 承载即 manifest 条目中102 partition字段的运行时表示。Snapshot log当前快照的历史日志官方定义snapshot loghistory table是记录表当前快照如何随时间变化的元数据日志内容是一组时间戳 快照 ID对当前快照在何时变更、变更成了哪个快照 ID。它作为snapshot-log字段存储在表元数据中规范位置见 format/spec.md 的### Table Metadata and Snapshots章节。表元数据 JSON 中相关字段长这样节选自规范附录 Ccurrent-snapshot-id: 3051729675574597004, snapshots: [ { snapshot-id: 3051729675574597004, timestamp-ms: 1515100955770, summary: { operation: append }, manifest-list: s3://b/wh/.../s1.avro, schema-id: 0 } ], snapshot-log: [ { snapshot-id: 3051729675574597004, timestamp-ms: 1515100955770 } ]注意规范中一句关键说明Snapshots are not serialized separately. Instead, they are stored in the table metadata JSON.——快照不是独立文件而是直接内嵌在表元数据 JSON 中snapshot-log只是当前快照main 分支变更历史的精简日志与完整快照列表snapshots并存。参考实现中这组概念的落点非常集中core/src/main/java/org/apache/iceberg/TableMetadata.java 持有private final ListHistoryEntry snapshotLog字段snapshotLog()方法对外暴露日志条目类型是 api/src/main/java/org/apache/iceberg/HistoryEntry.java 接口仅两个方法timestampMillis()变更时间戳与snapshotId()变更后的当前快照 ID与术语表时间戳和 ID 的对定义完全一致TableMetadata内部 Builder 中setRef针对main分支时会执行currentSnapshotId ref.snapshotId()并向snapshotLog追加一条SnapshotLogEntry反之removeRef(main)时snapshotLog.clear()——即日志只随 main 分支当前快照推进这与当前快照如何随时间变化的语义吻合JSON 序列化侧core/src/main/java/org/apache/iceberg/TableMetadataParser.java 定义了常量SNAPSHOT_LOG snapshot-log读写表元数据 JSON 时遍历metadata.snapshotLog()序列化为上述条目列表。小结六个术语在元数据链路中的位置术语存储位置核心作用Snapshot表元数据 JSON 的snapshots列表表在某一时刻的完整状态指向一个 manifest listManifest list快照manifest-list指向的 Avro 文件manifest 的索引携带分区值范围与文件计数加速规划Manifest filemanifest list 列出的 Avro 文件列出快照的一部分数据/删除文件及其分区元组、列级统计Partition spec表元数据 JSON 的partition-specs定义源列 transform驱动分区谓词推导支持演化Partition tuplemanifest 中每个 data file 的partition字段文件内所有行共享的分区值原样存储用于扫描过滤Snapshot log表元数据 JSON 的snapshot-log当前快照的 (timestamp-ms, snapshot-id) 变更历史这些概念共同构成了 Iceberg 单节点快速规划的基础从元数据指针出发经 manifest list 的范围概要跳过无用的 manifest再经 manifest 中的分区元组与列级统计裁剪数据文件。进一步的字段级细节含 v1/v2 差异、序列号继承规则可继续查阅 format/spec.md 的### Manifests、### Snapshots、### Table Metadata and Snapshots章节以及 docs/docs/performance.md 对 scan planning 过程的完整描述。赞分享数据湖湖仓一体大数据【免费下载链接】icebergApache Iceberg项目地址https://gitcode.com/gh_mirrors/iceberg5/iceberg点击查看免费下载相关推荐Apache Iceberg 核心术语完全指南Catalog、Snapshot 与 Manifest 元数据体系解析Apache Iceberg 核心术语完全指南Catalog、Snapshot 与 Manifest 元数据体系解析 本文是 Apache Iceberg 官数据湖大数据数据存储Apache Iceberg 核心术语全解读从 Snapshot 到 Snapshot Log 的元数据体系Apache Iceberg 核心术语全解读从 Snapshot 到 Snapshot Log 的元数据体系 导读 本篇文章以 Apache Iceberg大数据数据湖OLAP数据存储Docker CLI manifest inspect 命令详解查看镜像 Manifest 与多架构 Manifest ListDocker CLI manifest inspect 命令详解查看镜像 Manifest 与多架构 Manifest List 导读 docker maniCLI开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考