Apache Iceberg Puffin 文件格式规范详解:结构与实现
大数据数据湖OLAP数据存储【免费下载链接】icebergApache Iceberg项目地址https://gitcode.com/gh_mirrors/iceberg4/iceberg点击查看免费下载本文是 Apache Iceberg 中Puffin 文件格式的完整技术指南讲解这一专用于存储数据索引与统计信息的文件格式的二进制布局、Footer 元数据 JSON 结构、支持的 Blob 类型与压缩编解码器并结合仓库内core模块的读写实现与测试用例深入印证格式细节。读完本文你将能理解 Puffin 文件的字节级结构、自行编写符合规范的 Puffin 文件读写器并掌握 Iceberg 中 Puffin 统计文件StatisticsFile的接入方式。Puffin 是什么为索引与统计而生Puffin 是一种为 Apache Iceberg 设计的文件格式专门用来存放无法直接放入 Iceberg Manifest 中的数据索引和统计信息。一个 Puffin 文件包含若干任意类型的信息片段规范中称为blob以及解释这些 blob 所必需的元数据。Iceberg 当前支持的 blob 类型详见后文 Blob 类型 一节。从 Iceberg 的表模型看Puffin 文件通过StatisticsFile接口被挂载到某个快照上。该接口定义在 api/src/main/java/org/apache/iceberg/StatisticsFile.java 中包含所关联的snapshotId、文件路径、文件总大小、Puffin Footer 的大小以及文件内的BlobMetadata列表。其注释明确指出统计信息是informational的读取器可以选择忽略不依赖统计信息也能正确读取表数据——这保证了 Puffin 作为辅助信息文件的安全性与可选性。文件结构符合规范的 Puffin 文件具有如下整体布局Magic Blob₁ Blob₂ ... Blobₙ Footer其中Magic4 个字节0x50 0x46 0x41 0x31即 ASCII 字符P F A 1取自海雀属学名Fratercula arcticaPuffin与版本号 1位于文件开头Blobᵢ文件中的第 i 个 blob由应用程序依据 Footer 中的元数据自行解释Footer文件尾部定长结构具体见下文。当前 Puffin 格式只有一个版本v1即由Magic末字节0x31所标识的版本。仓库中 PuffinFormat.java 的实现与之完全一致static byte[] getMagic() { return new byte[] {0x50, 0x46, 0x41, 0x31}; }写入时blob 数据按序连续落盘每个 blob 的起始偏移量offset与长度length记录在 Footer 中读取器据此定位并读取任意 blob。测试用例 TestPuffinReader.java 也验证了这一布局第二个 blob 的offset恰好等于第一个 blob 的offset length。Footer 结构Footer 具有如下固定布局Magic FooterPayload FooterPayloadSize Flags Magic各组成部分组成部分长度/类型说明Magic4 字节与文件开头相同的魔数0x50 0x46 0x41 0x31FooterPayload变长描述文件中所有 blob 的 UTF-8 编码 JSON 负载FileMetadata对象可选压缩FooterPayloadSize4 字节整数FooterPayload的字节长度若压缩则为压缩后的长度小端序存储Flags4 字节布尔标志位Magic4 字节结尾魔数与开头相同关于Flags的位定义规范规定字节 0第 1 个字节bit 0最低位FooterPayload是否被压缩其余位保留给未来使用写入时必须置 0其余 3 个字节全部保留给未来使用写入时必须置 0。规范同时明确4 字节整数一律采用有符号二进制补码、小端序存储。对应实现见 PuffinFormat.java 的writeIntegerLittleEndian/readIntegerLittleEndian以及 PuffinWriter.writeFooter 中 Magic payload size flags Magic 的写出顺序。在 PuffinFormat.java 中还可以看到 Footer 尾部定长结构Footer Struct的常量定义static final int FOOTER_STRUCT_PAYLOAD_SIZE_OFFSET 0; // payload 大小字段 static final int FOOTER_STRUCT_FLAGS_OFFSET 4; // flags 字段 static final int FOOTER_STRUCT_FLAGS_LENGTH 4; // flags 占 4 字节 static final int FOOTER_STRUCT_MAGIC_OFFSET 8; // 结尾魔数读取器正是利用这些偏移从文件末尾反向定位并校验 Footer先读末尾定长结构校验结尾Magic再读出FooterPayloadSize反推 Footer 总长度最后从fileSize - footerSize处整段读取 Footer 并校验开头的Magic见 PuffinReader.fileMetadata。Footer PayloadFileMetadata 与 BlobMetadataFooterPayload要么不压缩要么以LZ4 单帧压缩携带内容大小的形式存放其内容是 UTF-8 编码的 JSON表示一个FileMetadata对象。FileMetadataFileMetadata字段如下字段名字段类型必填描述blobsBlobMetadata 对象列表是文件中所有 blob 的元数据列表propertiesJSON 对象字符串值否任意元信息存储如写入方标识/版本规范推荐设置的属性见 Common propertiesBlobMetadataBlobMetadata字段如下字段名字段类型必填描述typeJSON 字符串是blob 类型见 Blob 类型fieldsJSON 整数列表是计算该 blob 所依据的字段 ID 列表列表顺序用于计算 blob 内存储的草图sketchsnapshot-idJSON long是计算该 blob 所依据的 Iceberg 表快照 IDsequence-numberJSON long是计算该 blob 所依据的 Iceberg 表快照的序列号offsetJSON long是blob 内容在文件中的起始偏移量lengthJSON long是blob 在文件中存储的长度若压缩则为压缩后长度compression-codecJSON 字符串否见 压缩编解码器省略表示数据未压缩propertiesJSON 对象字符串值否关于该 blob 的任意元信息对应的 JSON 序列化/反序列化实现位于 FileMetadataParser.java其中 JSON 字段名type、fields、snapshot-id、sequence-number、offset、length、compression-codec、blobs、properties与规范表格逐字对应。测试 TestFileMetadataParser.java 给出了一个含两个 blob 的FileMetadata完整 JSON 示例{ blobs : [ { type : type-a, fields : [ 1 ], snapshot-id : 14, sequence-number : 3, offset : 4, length : 16 }, { type : type-bbb, fields : [ 2, 3, 4 ], snapshot-id : 77, sequence-number : 4, offset : 21474836470000, length : 79834 } ] }同时该测试还印证了校验规则blobs字段缺失会报Cannot parse missing field: blobs非数组会报Cannot parse blobs from non-arrayfields中的整数超出 32 位范围会被拒绝见 TestFileMetadataParser.java 与第 160-177 行。Blob 类型当前规范定义的 blob 类型如下。apache-datasketches-theta-v1这是 Apache DataSketches 库产生的compact Theta sketch的序列化形式。其构造方式为以默认种子default seed构建 Alpha 家族 sketch将每个去重后的单值distinct value使用Iceberg 的单值序列化single-value serialization转换为字节后逐一喂入 sketch。该 blob 的元数据可携带以下属性ndv由 sketch 推导出的去重值数量number of distinct values估计值。仓库中该类型以常量形式定义在 StandardBlobTypes.javapublic static final String APACHE_DATASKETCHES_THETA_V1 apache-datasketches-theta-v1;在实际使用中Spark 读取端的 SparkScan.java 会遍历table.statisticsFiles()当 blob 类型等于APACHE_DATASKETCHES_THETA_V1时用它来辅助估算统计信息——这是该标准 blob 类型在 Iceberg 引擎侧的真实消费场景。压缩编解码器blob 数据可以保持未压缩也可以使用下述编解码器之一压缩为保证最大互操作性其他编解码器不被支持。编解码器名称描述lz4单个 LZ4 压缩帧frame且必须携带内容大小content sizezstd单个 Zstandard 压缩帧且必须携带内容大小仓库中对应枚举定义在 PuffinCompressionCodec.javapublic enum PuffinCompressionCodec { /** No compression */ NONE(null), /** LZ4 single compression frame with content size present */ LZ4(lz4), /** Zstandard single compression frame with content size present */ ZSTD(zstd), }需要留意的是当前仓库实现的实际支持情况在 PuffinFormat.java 的compress/decompress中ZSTD 已通过 aircompressor 的ZstdCompressor/ZstdDecompressor完整落地LZ4 分支仍带有 TODO注明需要 LZ4 frame 压缩器支持。这一限制同样体现在测试中TestPuffinWriter.testEmptyFooterCompressed调用compressFooter()时会抛出Unsupported codec: LZ4见 TestPuffinWriter.java而 zstd 压缩写入/读取有对应的测试资源v1/sample-metric-data-compressed-zstd.bin见 PuffinFormatTestUtil.java。因此在实际使用中blob 与 Footer 的压缩建议使用 zstd或保持未压缩。此外规范还定义了Footer 压缩的默认编解码器为 LZ4FOOTER_COMPRESSION_CODEC PuffinCompressionCodec.LZ4见 PuffinFormat.java当 Flags 的FOOTER_PAYLOAD_COMPRESSED位被置位时读取端默认按 LZ4 帧解压 Footer。通用属性Common properties写入 Puffin 文件时规范推荐在FileMetadata的properties字段中设置以下属性created-by写入该文件的应用程序的可读标识及其版本例如Trino version 381。仓库中以常量定义在 StandardPuffinProperties.javapublic static final String CREATED_BY_PROPERTY created-by;写入端通过 Puffin.WriteBuilder.createdBy 便捷设置。测试中可看到createdBy(Test 1234)写出的文件在读取时fileMetadata.properties()为{created-by: Test 1234}见 TestPuffinReader.java。仓库实现读写 Puffin 文件规范之外Iceberg 在core模块的org.apache.iceberg.puffin包中提供了完整的 Java 读写实现核心 API 集中在 Puffin.java入口如下// 写入创建 PuffinWriter PuffinWriter writer Puffin.write(outputFile) .createdBy(my-app version 1.0) // 设置文件级 created-by 属性 .set(custom-prop, value) // 设置任意文件级属性 // .compressFooter() // 压缩 Footer当前仓库实现会抛 Unsupported codec: LZ4 // .compressBlobs(PuffinCompressionCodec.ZSTD) // 设置 blob 默认压缩 .build(); // 逐个添加 blob writer.add(new Blob( my-blob-type, ImmutableList.of(1), // 计算依据的字段 ID 列表 1234567890L, // snapshot-id 42L, // sequence-number ByteBuffer.wrap(data), PuffinCompressionCodec.ZSTD, // 该 blob 的压缩方式可覆盖默认 ImmutableMap.of(ndv, 1000))); // blob 级属性 writer.finish(); // 或直接 close()隐式 finish writer.footerSize(); writer.fileSize(); writer.writtenBlobsMetadata();写入流程的关键实现见 PuffinWriter.java每个 blob 添加时先写文件头Magic记录当前输出流位置作为fileOffset按blob 自身请求的压缩方式优先、否则使用写入器默认压缩的规则压缩后落盘并在内存中累积对应的BlobMetadata含 offset、压缩后 length、codec 名称。finish()时再整体写出 Footer见 PuffinWriter.finish。// 读取创建 PuffinReader PuffinReader reader Puffin.read(inputFile) // .withFileSize(...) // 已知文件大小时传入可提升读取性能 // .withFooterSize(...) // 已知 Footer 大小时传入可提升读取性能 .build(); FileMetadata fileMetadata reader.fileMetadata(); // 解析 Footer 元数据 for (BlobMetadata blobMeta : fileMetadata.blobs()) { // ... } IterablePairBlobMetadata, ByteBuffer blobs reader.readAll(blobMetadataList); reader.close();读取流程的关键实现见 PuffinReader.javafileMetadata()从文件末尾定位并校验 Footer、解析出FileMetadatareadAll按offset升序对 blob 排序后逐个 seek 读取、按compression-codec解压。若输入流实现了RangeReadable读取 Footer 会使用范围读优化见 PuffinReader.readInput。测试资源与格式验证仓库在core/src/test中提供了完整的格式一致性测试用静态二进制资源比对写入结果可直接作为格式规范的参考样例测试资源位于 core/src/test/resources/org/apache/iceberg/puffin/v1empty-puffin-uncompressed.bin空文件无 blob、Footer 未压缩的参考二进制其 Footer 大小为 28 字节sample-metric-data-uncompressed.bin含两个 blob、未压缩的参考二进制sample-metric-data-compressed-zstd.bin含两个 blob、zstd 压缩的参考二进制Footer 大小为 314 字节。测试类 TestPuffinWriter.java 与 TestPuffinReader.java 分别验证写入字节与参考文件完全一致、读取结果与写入内容完全一致包括 blob 内包含\u0000与 emoji 的二进制数据往返见 TestPuffinReader 第 133-140 行。对于希望自行实现 Puffin 文件读写器的场景建议以 format/puffin-spec.md仓库中的规范原文与本站文档内容一致为准并结合上述测试二进制逐字节核对实现可确保与 Iceberg 生态完全互通。小结Puffin 是 Iceberg 生态中承载索引与统计信息的轻量自描述文件格式它以固定的 4 字节魔数开头、以自描述 JSON Footer 收尾中间连续存放任意数量的 blob每个 blob 通过type、fields、snapshot-id、sequence-number、offset、length等元数据字段被精确定位与解释。当前规范定义了apache-datasketches-theta-v1一种标准 blob 类型与lz4/zstd两种压缩编解码器并通过created-by等通用属性保证文件的来源可追溯。在 Apache Iceberg 中Puffin 文件以StatisticsFile的形式挂载到快照上供查询引擎如 Spark在扫描时辅助估算统计信息同时保持可选择性——任何读取器都可以安全地忽略它。赞分享大数据数据湖OLAP数据存储【免费下载链接】icebergApache Iceberg项目地址https://gitcode.com/gh_mirrors/iceberg4/iceberg点击查看免费下载相关推荐Apache Iceberg Puffin 文件格式规范为索引与统计信息而生的 Blob 存储格式Apache Iceberg Puffin 文件格式规范为索引与统计信息而生的 Blob 存储格式 Puffin 是 Apache Iceberg 定义的一种数据湖大数据数据存储Apache Iceberg Puffin 文件格式完全指南索引与统计数据的标准存储载体Apache Iceberg Puffin 文件格式完全指南索引与统计数据的标准存储载体 Puffin 是 Apache Iceberg 定义的一种文件格式数据湖大数据数据存储safetensors格式规范详解从文件结构到数据类型支持safetensors格式规范详解从文件结构到数据类型支持 safetensors是一种专为机器学习设计的简单、安全的张量存储格式旨在替代不安全的pickl序列化人工智能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

绝缘电阻测试仪如何选?菊水TOS9301S与TOS9201S实操对比与维护指南

绝缘电阻测试仪如何选?菊水TOS9301S与TOS9201S实操对比与维护指南

做电气安规这一行,手里没有一台靠谱的绝缘电阻测试仪,很多出厂检验项目根本走不完。菊水TOS9301S和TOS9201S这两款绝缘电阻测试仪,算是我这几年在产线和实验室里用得比较多的设备了。今天不聊说明书上那一套,就站在实际使用者的角…

2026/10/13 10:25:17 阅读更多 →
TCT亚洲展材料参展复盘:从全系列3D打印材料到工程料转化

TCT亚洲展材料参展复盘:从全系列3D打印材料到工程料转化

TCT亚洲展散场那天,我把展位上的最后一块试片样本收进箱子,刚转身就被一位做模具的工程师拉住:你们这个材料,能先寄几公斤工程料试试吗?那一刻我知道,这一趟没白跑。我们这次带着ANTINSKY全系列3D打印材料来…

2026/10/13 10:50:30 阅读更多 →
MAB 5.0建模规范实战指南:让Simulink模型可读可测可维护

MAB 5.0建模规范实战指南:让Simulink模型可读可测可维护

前段时间给一个做底盘域控制器的项目做模型评审,模型有一千多个模块,状态机里的状态也有几十个。评审会开到最后,大家争的不是控制逻辑,而是“这个信号名到底是车速还是轮速”这种问题。那一刻我意识到,MATLAB平台上这…

2026/10/13 10:50:33 阅读更多 →

最新新闻

CloudPods LLM 推理部署与 aiproxy 网关自动关联全解:从 llm-deployment-create 到 OpenAI 兼容调用

CloudPods LLM 推理部署与 aiproxy 网关自动关联全解:从 llm-deployment-create 到 OpenAI 兼容调用

后端云原生运维虚拟化人工智能AI 应用 【免费下载链接】cloudpods 开源、云原生的多云管理及混合云融合平台 项目地址: https://gitcode.com/yunionio/cloudpods 点击查看 免费下载 在 CloudPods 的多云管理平台中,本地 GPU 推理集群与统一 API 网关是两…

2026/10/13 12:26:21 阅读更多 →
掌握IMX577 Datasheet:从寄存器配置到驱动调试实战

掌握IMX577 Datasheet:从寄存器配置到驱动调试实战

简介:索尼IMX577-AACK-C是一款由索尼半导体推出的背照堆栈式CMOS图像传感器,对角线长度约为七点八六毫米,尺寸规格为二点三分之一型,官方数据手册适合摄像头模组、工业检测、医疗影像与安防监控领域的硬件工程师阅读,可…

2026/10/13 12:26:21 阅读更多 →
【无人机路径规划】基于粒子群优化和遗传算法的水陆两栖无人机任务规划和执行研究附Matlab代码

【无人机路径规划】基于粒子群优化和遗传算法的水陆两栖无人机任务规划和执行研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和数学建模资料 &…

2026/10/13 12:26:21 阅读更多 →
Ableton Live12下载安装教程AbletonLive12下载 Win/Mac 2025电音编曲软件专业版Win/Mac Ableton Live Suite 12.3.5含原厂采样库43G

Ableton Live12下载安装教程AbletonLive12下载 Win/Mac 2025电音编曲软件专业版Win/Mac Ableton Live Suite 12.3.5含原厂采样库43G

Win/Mac AbletonLive12 含视频安装教程下载链接https://www.dygdu.com/soft/live.htmlAbleton Live 12 是德国音乐软件公司 Ableton 开发的最新一代数字音频工作站(DAW),于2023年9月发布预览版,2024年正式推出。作为 Live 系列的重…

2026/10/13 12:26:21 阅读更多 →
Eclipse Navigate菜单全解析:从定位到跳转的快捷键指南

Eclipse Navigate菜单全解析:从定位到跳转的快捷键指南

很多人在 Eclipse 里写代码,处理得最顺的是输出代码,最抓狂的往往是找代码。你大概也有过这种时刻:一个类名明明见过,却要在 Project Explorer 里翻半天;一个方法跳转进去,明明是接口签名,实现还…

2026/10/13 12:26:21 阅读更多 →
三级降级链:RAG在向量库故障时不中断、不编造的工程实践

三级降级链:RAG在向量库故障时不中断、不编造的工程实践

做 RAG 检索最怕的不是模型笨,而是向量库在关键时刻掉链子——服务起不来、集合是空的、维度对不上,检索请求一进来就报错,整个问答系统直接瘫了。咱先把结论摆前面:RAG 做降级本身不难,难的是降级的时候不返回一个“看…

2026/10/13 12:25:20 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →