数据湖iceberg和spark集成

数据湖iceberg和spark集成

一、概述

为了解决数据存储和计算引擎之间的适配的问题,Netflix开发了Iceberg,2018年11月16日进入Apache孵化器,2020 年5月19成为Apache的顶级项目。Iceberg是一个面向海量数据分析场景的开放表格式(Table Format)。表格式(Table Format)可以理解为元数据以及数据文件的一种组织方式,处于计算框架(Flink,Spark…)之下,数据文件之上。

二、 特性

1、数据存储、计算引擎插件化

Iceberg提供一个开放通用的表格式(Table Format)实现方案,不和特定的数据存储、计算引擎绑定。目前大数据领域的常见数据存储(HDFS、S3…),计算引擎(Flink、Spark…)都可以接入Iceberg。在生产环境中,可选择不同的组件搭使用。甚至可以不通过计算引擎,直接读取存在文件系统上的数据。

2、实时流批一体

Iceberg上游组件将数据写入完成后,下游组件及时可读,可以满足实时场景。并且Iceberg同时提供了流/批读接口、流/批写接口。可以在同一个流程里, 同时处理流数据和批数据,大大简化了ETL链路。

3、数据表演化(Table Evolution)

Iceberg可以通过SQL的方式进行表级别模式演进。进行这些操作的时候,代价极低。 不存在读出数据重新写入或者迁移数据这种费时费力的操作。

4、模式演化(Schema Evolution)

Iceberg支持下面几种模式演化:

ADD:向表或者嵌套结构增加新列

Drop:从表中或者嵌套结构中移除一列

Rename:重命名表中或者嵌套结构中的一列

Update:将复杂结构(struct, map<key, value>, list)中的基本类型扩展类型长度, 比如tinyint修改成int.

Reorder:改变列或者嵌套结构中字段的排列顺序

在表中Iceberg 使用唯一ID来定位每一列的信息。新增一个列的时候,会新分配给它一个唯一ID, 并且绝对不会使用已经被使用的ID。

5、分区演化(Partition Evolution)

Iceberg可以在一个已存在的表上直接修改,因为Iceberg的查询流程并不和分区信息直接关联。当我们改变一个表的分区策略时,对应修改分区之前的数据不会改变, 依然会采用老的分区策略,新的数据会采用新的分区策略,也就是说同一个表会有两种分区策略,旧数据采用旧分区策略,新数据采用新新分区策略, 在元数据里两个分区策略相互独立,不重合。在查询数据的时候,如果存在跨分区策略的情况,则会解析成两个不同执行计划,如Iceberg官网提供图所示:
在这里插入图片描述

6、列顺序演化(Sort Order Evolution)

Iceberg可以在一个已经存在的表上修改排序策略。修改了排序策略之后, 旧数据依旧采用老排序策略不变。往Iceberg里写数据的计算引擎总是会选择最新的排序策略, 但是当排序的代价极其高昂的时候, 就不进行排序了。

7、隐藏分区(Hidden Partition)

Iceberg的分区信息并不需要人工维护, 它可以被隐藏起来. 不同其他类似Hive 的分区策略, Iceberg的分区字段/策略(通过某一个字段计算出来),可以不是表的字段和表数据存储目录也没有关系。在建表或者修改分区策略之后,新的数据会自动计算所属于的分区。在查询的时候同样不用关系表的分区是什么字段/策略,只需要关注业务逻辑,Iceberg会自动过滤不需要的分区数据。

正是由于Iceberg的分区信息和表数据存储目录是独立的,使得Iceberg的表分区可以被修改,而且不和涉及到数据迁移。

8、快照数据查询(Time Travel snapshot)

Iceberg提供了查询表历史某一时间点的快照数据和恢复到某一时间点数据的能力。

9、支持事务(ACID)

Iceberg通过提供事务(ACID)的机制,使其具备了upsert的能力并且使得边写边读成为可能,从而数据可以更快的被下游组件消费。通过事务保证了下游组件只能消费已commit的数据,而不会读到部分甚至未提交的数据。

10、基于乐观锁的并发支持

Iceberg基于乐观锁提供了多个程序并发写入的能力并且保证数据线性一致。

11、文件级数据剪裁

Iceberg的元数据里面提供了每个数据文件的一些统计信息,比如最大值,最小值,Count计数等等。因此,查询SQL的过滤条件除了常规的分区,列过滤,甚至可以下推到文件级别,大大加快了查询效率。

其他数据湖框架的对比

在这里插入图片描述

二、存储结构

在这里插入图片描述

2.1 数据文件 data files

数据文件是Apache Iceberg表真实存储数据的文件,一般是在表的数据存储目录的data目录下,如果我们的文件格式选择的是parquet,那么文件是以“.parquet”结尾。

例如:00000-0-atguigu_20230203160458_22ee74c9-643f-4b27-8fc1-9cbd5f64dad4-job_1675409881387_0007-00001.parquet 就是一个数据文件。

Iceberg每次更新会产生多个数据文件(data files)。

2.2 表快照 Snapshot

快照代表一张表在某个时刻的状态。每个快照里面会列出表在某个时刻的所有 data files 列表。data files是存储在不同的manifest files里面,manifest files是存储在一个Manifest list文件里面,而一个Manifest list文件代表一个快照。

2.3 清单列表 Manifest list

manifest list是一个元数据文件,它列出构建表快照(Snapshot)的清单(Manifest file)。这个元数据文件中存储的是Manifest file列表,每个Manifest file占据一行。每行中存储了Manifest file的路径、其存储的数据文件(data files)的分区范围,增加了几个数文件、删除了几个数据文件等信息,这些信息可以用来在查询时提供过滤,加快速度。

例如:snap-6746266566064388720-1-52f2f477-2585-4e69-be42-bbad9a46ed17.avro就是一个Manifest List文件。

2.4 清单文件 Manifest file

Manifest file也是一个元数据文件,它列出组成快照(snapshot)的数据文件(data files)的列表信息。每行都是每个数据文件的详细描述,包括数据文件的状态、文件路径、分区信息、列级别的统计信息(比如每列的最大最小值、空值数等)、文件的大小以及文件里面数据行数等信息。其中列级别的统计信息可以在扫描表数据时过滤掉不必要的文件。

Manifest file是以avro格式进行存储的,以“.avro”后缀结尾,例如:52f2f477-2585-4e69-be42-bbad9a46ed17-m0.avro。

三、与 Spark SQL集成

1、 Spark 配置 Catalog

Spark中支持两种Catalog的设置:hive和hadoop,Hive Catalog就是Iceberg表存储使用Hive默认的数据路径,Hadoop Catalog需要指定Iceberg格式表存储路径。

# Hive Catalog
spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
spark.sql.catalog.hive_catalog=org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.hive_catalog.type=hive
spark.sql.catalog.hive_catalog.uri=thrift://hadoop1:9083
#  Hadoop Catalog
spark.sql.catalog.hadoop_catalog = org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.hadoop_catalog.type = hadoop
spark.sql.catalog.hadoop_catalog.warehouse = hdfs://hadoop1:8020/warehouse/spark-iceberg
# 配置默认使用的catalog
spark.sql.defaultCatalog=hive_catalog

2、 SQL 操作

2.1、 创建表

CREATE TABLE hive_catalog.tmp.sample1
(
    id   bigint COMMENT 'unique id',
    data string
) USING iceberg;
 

PARTITIONED BY (partition-expressions) :配置分区

LOCATION ‘(fully-qualified-uri)’ :指定表路径

COMMENT ‘table documentation’ :配置表备注

TBLPROPERTIES (‘key’=‘value’, …) :配置表属性

表属性:https://iceberg.apache.org/docs/latest/configuration/

对Iceberg表的每次更改都会生成一个新的元数据文件(json文件)以提供原子性。默认情况下,旧元数据文件作为历史文件保存不会删除。如果要自动清除元数据文件,在表属性中配置:。

#会在每个新创建的元数据文件之后删除旧的元数据文件
'write.metadata.delete-after-commit.enabled'='true',
'write.metadata.previous-versions-max'='100'

2.2、创建分区表

(1)分区表

CREATE TABLE hive_catalog.tmp.sample2 (
  id bigint,
  data string,
  category string)
USING iceberg
PARTITIONED BY (category);

(2)创建隐藏分区表

CREATE TABLE hive_catalog.tmp.sample3 (
  id bigint,
  data string,
  category string,
  ts timestamp)
USING iceberg
PARTITIONED BY (bucket(16, id), days(ts), category);

支持的转换有:</

  • 28
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小中.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值