一、Iceberg产生背景
随着大数据存储和处理需求的多样化,如何构建一个统一的数据湖存储,并在其上进行多种形式的数据分析成了企业构建大数据生态的一个重要方向。Netflix 发起的 Apache Iceberg 项目具备 ACID 能力的表格式成为了大数据、数据湖领域炙手可热的方向。
Apache Iceberg 是由 Netflix 开发开源,并于 2018年11月16日进入 Apache 孵化器。Netflix的数据湖原先是借助Hive来构建,但发现Hive在设计上的诸多缺陷之后,开始转为自研Iceberg。使用hive面临的问题如下:
- 海量分区操作耗时。
- 元数据分属MySQL和HDFS管理,写入操作本身的原子性难以保证;
- Hive Metastore没有文件级别的统计信息,这使得filter只能下推到partition级别,对上层分析性能损耗。
- Hive对底层文件系统的复杂语义依赖,使得数据湖难以构建在成本更低的S3上。
总体来说,Netflix设计Iceberg的核心诉求可以归纳为如下:
二、Iceberg简介
2.1 Iceberg是什么
Apache Iceberg 是一种用于跟踪超大规模表的新格式,是专门为对象存储(如S3)而设计的。具备如下能力:
- 构建于存储格式之上的数据组织方式
- 提供 ACID 能力,提供一定的事务特性和并发能力
- 提供行级别的数据修改能力
- 确保 Schema 的准确性,提供一定的 Schema 扩展能力
2.2 Iceberg功能特性
- 模式演化:支持添加,删除,更新或重命名,并且没有副作用
- 隐藏分区:可以防止导致错误提示或非常慢查询的用户错误
- 分区布局演变:可以随着数据量或查询模式的变化而更新表的布局
- 快照控制:可实现使用完全相同的表快照的可重复查询,或者使用户轻松检查更改
- 版本回滚:使用户可以通过将表重置为良好状态来快速纠正问题
- 快速扫描数据:无需使用分布式SQL引擎即可读取表或查找文件
- 数据修剪优化:使用表元数据使用分区和列级统计信息修剪数据文件
- 兼容性好:可以存储在任意的云存储系统和HDFS中
- 支持事务:序列化隔离,表更改是原子性的,读者永远不会看到部分更改或未提交的更改
- 高并发:高并发写入器使用乐观并发,即使写入冲突,也会重试以确保兼容更新成功
2.3支持计算引擎/sql引擎
2.3.1 Flink
Apache Iceberg同时支持Apache Flink的DataStream API和Table API,以将记录写入Iceberg表。目前,集成了iceberg和apache flink 1.11.x。支持的功能如下所示:
2.3.2 Spark
iceberg使用Apache Spark的DataSourceV2 API实现数据源和目录实现。Spark DSv2是一个不断发展的API,在Spark版本中提供了不同级别的支持:
2.3.3 Trino
Trino是一个基于内存的MPP计算引擎,通过并行+内存的计算方式,可以大大提高计算速度,再加上一些优化(例如剪枝、谓词下推等),就可以达到大数据量计算任务下的秒级响应。通过在trino中配置iceberg connector可以操作iceberg表。
三、Iceberg基本原理
3.1 Iceberg基本概念
如图所示是iceberg的表结构,其中相关概念如下所述:
- VersionMetadata
存储当前版本的元数据信息(所有snapshot信息)。
- Snapshot(Manifest list)
快照文件,也成为清单列表文件,是以avro 格式进行存储,以 snap- 开头的。每次更新都会产生一个清单列表文件,代表一张表在某个时刻的状态。Snap*.avro里面存储的是清单文件的列表,每个清单文件占据一行。每行中存储了清单文件的路径、清单文件里面存储数据文件的分区范围、增加了几个数据文件、删除了几个数据文件等信息。这些信息可以用来在查询时提供过滤。
- Manifest
清单文件其实是元数据文件,其里面列出了组成某个快照(snapshot)的数据文件列表。每行都是每个数据文件的详细描述,包括数据文件的状态、文件路径、分区信息、列级别的统计信息(比如每列的最大最小值、空值数等)、文件的大小以及文件里面数据的行数等信息。其中列级别的统计信息在 Scan 的时候可以为算子下推提供数据,以便可以过滤掉不必要的文件。
清单文件是以 avro 格式进行存储的,所以是以 .avro 后缀结尾的,比如 d5ba704c-1453-4f18-9077-6944baa1b3f2-m0.avro
每次更新会产生一个或多个清单文件。
- Datafile
数据文件(data files)是 Apache Iceberg 表真实存储数据的文件,一般是在表的数据存储目录的 data 目录下。如果我们的文件格式选择的是 parquet,那么文件是以 .parquet 结尾,
比如 00000-0-0eca9076-9c03-4077-baa9-e68769e15c58-00001.parquet 就是一个数据文件。
3.2 Iceberg快照设计
核心思想:在时间轴上跟踪表的所有变化
- 快照(snapshot)表示表数据文件的一个完整集合
- 每次更新操作会生成一个新的快照。
快照隔离
- 读操作仅适用于当前已生成的快照
- 写操作会生成新的隔离快照,并在写完成后原子性提交
3.3 Iceberg元数据
Iceberg提供了表级别的抽象接口,自己在文件中维护表的元数据信息(而非通过HMS维护)。上图中,在HMS元数据存储的是iceberg表的入口信息。即iceberg表的当前版本的元数据入口路径信息。在实际应用中,如下图所示,表order的元数据信息存放在HMS上,存放的信息内容metadata_location= hdfs://node1:9000/user/hive/warehouse/orders/metadata/00009-7aa28ddf-34fe-496b-8888-3b806a8edb7a.metadata.json 是order表当前快照元信息入口。previous_metadata_location是上一个快照信息的入口。
四、附录
【参考链接】
[1]https://iceberg.apache.org iceberg官网
[2]http://iceberg.apache.org/releases iceberg版本发布
[3]https://github.com/apache/iceberg iceberg github
[4]http://iceberg.apache.org/spec/ iceberg表格式说明文档
[5][一篇文章掌握 delta、iceberg 和 hudi 三大开源数据湖方案](https://mp.weixin.qq.com/s?__biz=MzA5MTc0NTMwNQ==&mid=2650719887&idx=2&sn=c08c01990810a01bbfe7e94e70a53f4b&chksm=887ddbf9bf0a52efda132cb787313051a52b5b33dc4ef63f54b395fd24bf125a844942f97972&scene=21" \l "wechat_redirect)
[6]大数据架构变革进行时:为什么腾讯看好 Apache Iceberg?
[7] Flink + Iceberg 全场景实时数仓的建设实践_huzechen的博客-CSDN博客