写点什么

数据湖(十一):Iceberg 表数据组织与查询

作者:Lansonli
  • 2022-10-26
    广东
  • 本文字数:1806 字

    阅读完需:约 6 分钟

数据湖(十一):Iceberg表数据组织与查询

Iceberg 表数据组织与查询

一、下载 avro-tools jar 包

由于后期需要查看 avro 文件内容,我们可以通过 avro-tool.jar 来查看 avro 数据内容。可以在以下网站中下载 avro-tools 对应的 jar 包,下载之后上传到 node5 节点上:


https://mvnrepository.com/artifact/org.apache.avro/avro-tools


查看 avro 文件信息可以直接执行如下命令,可以将 avro 中的数据转换成对应的 json 数据。


[root@node5 ~]# java -jar /software/avro-tools-1.8.1.jar tojson snap-*-wqer.avro
复制代码

二、在 Hive 中创建 Iceberg 表并插入数据

在 Hive 中创建 Iceberg 格式表,并插入如下数据:


#在Hive中创建iceberg格式表create table test_iceberg_tbl1(id int ,name string,age int) partitioned by (dt string) stored by 'org.apache.iceberg.mr.hive.HiveIcebergStorageHandler';
#插入如下数据insert into test_iceberg_tbl1 values (1,"zs",21,"20211212");insert into test_iceberg_tbl1 values (2,"ls",22,"20211212");insert into test_iceberg_tbl1 values (3,"ww",23,"20211213");insert into test_iceberg_tbl1 values (4,"ml",24,"20211213");insert into test_iceberg_tbl1 values (5,"tq",25,"20211213");
复制代码

三、查看 Iceberg 底层数据存储

下图为 Iceberg 表“test_iceberg_tbl1”在 HDFS 中存储的数据组织图:



通过上图我们可以看到有 5 个 Snapshot 快照,以上 5 个 Snapshot 实际上就是对应了 5 个 Manifest list 清单列表。

1、查询最新快照数据

为了了解 Iceberg 如何查询最新数据,可以参照下面这张图来详细了解底层实现。



查询 Iceberg 表数据时,首先获取最新的 metadata 信息,这里先获取到“00000-ec504.metadata.json”元数据信息,解析当前元数据文件可以拿到当前表的快照 id:“949358624197301886”以及这张表的所有快照信息,也就是 json 信息中 snapshots 数组对应的值。根据当前表的快照 id 值可以获取对应的 snapshot 对应的 avro 文件信息:“snap--32800.avro”,我们可以找到当前快照对应的路径,看到其包含的 Manifest 清单文件有 5 个:"*32800-m0.avro"、"*2abba-m0.avro"、"*d33de-m0.avro"、"*748bf-m0.avro"、"*b946e-m0.avro",读取该 Iceberg 格式表最新数据就是读取这几个文件中描述对应的 parquet 数据文件即可。


我们可以看到“snap-*-32800.avro”快照文件中不仅有包含的 manifest 路径信息,还有“added_data_files_count”、“existing_data_files_count”、“deleted_data_files_count”三个属性,Iceberg 根据 deleted_data_files_count 大于 0 来判断对应的 manifest 清单文件里面是不是被删除的数据,如果一个 manifest 清单文件该值大于 0 代表数据删除,读数据时就无需读这个 manifest 清单文件对应的数据文件。


根据 Manifest list 找到了各个对应的 manifest 清单文件,每个文件中描述了对应 parquet 文件存储的位置信息,可以看到在对应的 avro 文件中有“status”属性,该属性为 1 代表对应的 parquet 文件为新增文件,需要读取,为 2 代表 parquet 文件被删除。

2、查询某个快照的数据

Apache Iceberg 支持查询历史上任何时刻的快照,在查询时需要指定 snapshot-id 属性即可,这个只能通过 Spark/Flink 来查询实现,例如在 Spark 中查询某个快照数据如下:


spark.read.option("snapshot-id",6155408340798912701L).format("iceberg").load("path")
复制代码


查询某个快照数据的原理如下图所示(以查询快照 id 为“6155408340798912701”的数据为例):



通过上图可以看出,实际上读取历史快照数据和读取最新数据不同之处就是找到的 snapshot-id 不同而已,原理都是一样。

3、根据时间戳查看某个快照的数据

Apache iceberg 还支持通过 as-of-timestamp 参数执行时间戳来读取某个快照的数据,同样也是通过 Spark/Flink 来读取,Spark 读取代码如下:


spark.read.option("as-of-timestamp","时间戳").format("iceberg").load("path")
复制代码


实际上通过时间戳找到对应数据文件的原理与通过 snapshot-id 找到数据文件原理一样,在*.metadata.json 文件中,除了有“current-snapshot-id”、“snapshots”属性外还有“snapshot-log”属性,该属性对应的值如下:



我们可以看到其中有个 timestamp-ms 属性和 snapshot-id 属性,并且是按照 timestamp-ms 升序的。在 Iceberg 内部实现中,它会将 as-of-timestamp 指定的时间和 snapshot-log 数组里面每个元素的 timestamp-ms 进行比较,找出最后一个满足 timestamp-ms <= as-of-timestamp 对应的 snapshot-id,原理同上,通过 snapshot-id 再找到要读取的数据文件。


发布于: 刚刚阅读数: 5
用户头像

Lansonli

关注

微信公众号:三帮大数据 2022-07-12 加入

CSDN大数据领域博客专家,华为云享专家、阿里云专家博主、腾云先锋(TDP)核心成员、51CTO专家博主,全网六万多粉丝,知名互联网公司大数据高级开发工程师

评论

发布
暂无评论
数据湖(十一):Iceberg表数据组织与查询_数据湖_Lansonli_InfoQ写作社区