【Iceberg分析】调研Iceberg中表的原地演变

调研Iceberg中表的原地演变

文章目录

  • 调研Iceberg中表的原地演变
    • 原生非分区表
      • 文件关系图
      • 表的原地演变之表schema演变
        • 新增字段new_column
        • 文件关系变化图
        • 为新增字段写入数据
        • 文件关系变化图
        • 删除新增字段
        • 文件关系变化图
        • 新增字段new_column2
        • 文件关系变化图
        • 删除数据
        • 文件关系变化图
    • 原生分区表
      • Iceberg支持如下几种分区转换
      • 文件关系变化图
      • 表的原地演变之分区演变
        • 新增分区
        • 文件关系变化图
        • 删除分区
        • 删除数据
        • 文件关系变化图
    • 小结

以《基于spark3.4.2+iceberg1.6.1搭建本地阅读调试环境》为基础环境,调研原地演变特性

工程中iceberg_warehousespark.sql.catalog.local.warehouse 指定了 Iceberg 数据文件和元数据文件的存放路径。

原生非分区表

创建非分区原生表,并插入数据。

        // 1.创建库spark.sql("create database iceberg_db");// 2.新建表spark.sql("CREATE TABLE local.iceberg_db.table1 (id bigint, data string) USING iceberg ");// 3.第1次新增数据spark.sql("INSERT INTO local.iceberg_db.table1 VALUES (1, 'a'), (2, 'b'), (3, 'c')");// 4.第2次新增数据spark.sql("INSERT INTO local.iceberg_db.table1 VALUES (4, 'd'), (5, 'e'), (6, 'f')");// 5.第3次新增数据spark.sql("INSERT INTO local.iceberg_db.table1 VALUES (7, 'g'), (8, 'h'), (9, 'i')");

在这里插入图片描述

文件关系图

数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table1

新建表时,会触发元数据的变化,此时是没有数据文件的,所以只有v1.metadata.json文件。

  • snap-开头的是清单列表文件(manifest list)
  • 紧接着snap之后的数字开头的是清单文件(manifest file)

表的原地演变之表schema演变

新增字段new_column
        // 6.新增字段new_columnspark.sql("ALTER TABLE local.iceberg_db.table1 " +"ADD COLUMNS ( new_column string comment 'new_column docs' )");
文件关系变化图
数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
v5.metadata.json
ceberg_db.table1

v5.metadata.jsonschemas以数组的形式记录了不同的表schema。以schema-id区分。new_column字段上有对应的字段id3current-schema-id中是当前生效的schema-id

 "current-schema-id" : 1,
"schemas" : [ {"type" : "struct","schema-id" : 0,"fields" : [ {"id" : 1,"name" : "id","required" : false,"type" : "long"}, {"id" : 2,"name" : "data","required" : false,"type" : "string"} ]}, {"type" : "struct","schema-id" : 1,"fields" : [ {"id" : 1,"name" : "id","required" : false,"type" : "long"}, {"id" : 2,"name" : "data","required" : false,"type" : "string"}, {"id" : 3,"name" : "new_column","required" : false,"type" : "string","doc" : "new_column docs"} ]} ]
为新增字段写入数据
        // 7.为新增字段new_column增加数据spark.sql("INSERT INTO local.iceberg_db.table1 VALUES (10, 'j','new1'), (11, 'k','new2'), (12, 'l','new3')");Dataset<Row> result = spark.sql("select * from local.iceberg_db.table1");result.show();

查询结果

表的schema中新增字段在之前的记录以null填充展示。

+---+----+----------+
| id|data|new_column|
+---+----+----------+
|  7|   g|      null|
|  8|   h|      null|
|  9|   i|      null|
|  1|   a|      null|
|  2|   b|      null|
|  3|   c|      null|
| 10|   j|      new1|
| 11|   k|      new2|
| 12|   l|      new3|
|  4|   d|      null|
|  5|   e|      null|
|  6|   f|      null|
+---+----+----------+
文件关系变化图
数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
v5.metadata.json
v6.metadata.json
Manifest list
avro格式
Manifest file
avro格式
ceberg_db.table1
删除新增字段
        // 8.删除字段new_columnspark.sql("ALTER TABLE local.iceberg_db.table1 DROP COLUMNS new_column");Dataset<Row> result = spark.sql("select * from local.iceberg_db.table1");result.show();

查询结果

表schema的删除字段在,之前的记录全部除了删除字段,全部可以查询展示。

+---+----+
| id|data|
+---+----+
|  4|   d|
|  5|   e|
|  6|   f|
|  1|   a|
|  2|   b|
|  3|   c|
| 10|   j|
| 11|   k|
| 12|   l|
|  7|   g|
|  8|   h|
|  9|   i|
+---+----+
文件关系变化图
数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
v5.metadata.json
v6.metadata.json
v7.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table1

v7.metadata.jsoncurrent-schema-id中是当前生效的schema-id改为了0

新增字段new_column2
        // 9.删除字段new_columnspark.sql("ALTER TABLE local.iceberg_db.table1 " +"ADD COLUMNS ( new_column2 string comment 'new_column2 docs' )");
文件关系变化图
数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
v5.metadata.json
v6.metadata.json
v7.metadata.json
v8.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table1

v8.metadata.jsonschemas的变化,删除字段new_column的id3,不会再之后新增的new_column2不会再使用了。

"current-schema-id" : 2,
"schemas" : [ {"type" : "struct","schema-id" : 0,"fields" : [ {"id" : 1,"name" : "id","required" : false,"type" : "long"}, {"id" : 2,"name" : "data","required" : false,"type" : "string"} ]
}, {"type" : "struct","schema-id" : 1,"fields" : [ {"id" : 1,"name" : "id","required" : false,"type" : "long"}, {"id" : 2,"name" : "data","required" : false,"type" : "string"}, {"id" : 3,"name" : "new_column","required" : false,"type" : "string","doc" : "new_column docs"} ]
}, {"type" : "struct","schema-id" : 2,"fields" : [ {"id" : 1,"name" : "id","required" : false,"type" : "long"}, {"id" : 2,"name" : "data","required" : false,"type" : "string"}, {"id" : 4,"name" : "new_column2","required" : false,"type" : "string","doc" : "new_column2 docs"} ]
} ]
删除数据
        // 10.删除字段new_columnspark.sql("DELETE FROM local.iceberg_db.table1  where id in (2,5,10)");Dataset<Row> result = spark.sql("select * from local.iceberg_db.table1");result.show();
文件关系变化图
数据层
元数据层
catalog
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
v5.metadata.json
v6.metadata.json
v7.metadata.json
v8.metadata.json
v9.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table1

不同版本的metadata文件会使用不同的清单文件指向相同的数据文件,清单文件(manifest file)中的status字段取值说明,值1代表add,值2代表删除。

原生分区表

Iceberg支持如下几种分区转换

转换名称描述源字段类型结果类型
identityid值,默认没有转换函数。注意:如果用时间戳做为分区的话,每个时间戳是一个分区,随着数据的写入,元数据很快会崩溃AnySource type
bucket[N]哈希值],模Nint, long, decimal, date, time, timestamp, timestamptz, timestamp_ns, timestamptz_ns, string, uuid, fixed, binaryint
truncate[W]将字段按宽度截取int, long, decimal, string, binary与源字段类型一致,如果源字段是字符串则截取W长度,如果是int/long则相除W倍后取整
year将时间转换为年date, timestamp, timestamptz, timestamp_ns, timestamptz_nsint
month将时间转换为月date, timestamp, timestamptz, timestamp_ns, timestamptz_nsint
day将时间转换为日date, timestamp, timestamptz, timestamp_ns, timestamptz_nsint
hour将时间转换为小时timestamp, timestamptz, timestamp_ns, timestamptz_nsint
voidAlways produces nullAnySource type or int

创建分区原生表,使用分区转换进行隐藏分区,并插入数据。

        // 1.创建分区表,以month方法进行隐藏式分区spark.sql("CREATE TABLE local.iceberg_db.table2( id bigint, data string, ts timestamp) USING iceberg PARTITIONED BY (month(ts))");// 2.新增数据spark.sql("INSERT INTO local.iceberg_db.table2 VALUES (1, 'a', cast(1727601585 as timestamp)),(2, 'b', cast(1724923185 as timestamp)),(3, 'c', cast(1724919585 as timestamp))");

在这里插入图片描述

文件关系变化图

数据层
元数据层
catalog
ts_month=2024-08
ts_month=2024-09
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
Manifest list
avro格式
Manifest file
avro格式
ceberg_db.table2

Iceberg 通过获取列值并对其进行可选转换来生成分区值。建表时,ts字段类型是使用timestamp,默认使用带时区的timestamptz

v1.metadata.jsonpartition-specs以数组的形式记录了不同的表分区规则,以spec-id区分。default-spec-id中是当前生效的spec-id

  "default-spec-id" : 0,"partition-specs" : [ {"spec-id" : 0,"fields" : [ {"name" : "ts_month","transform" : "month","source-id" : 3,"field-id" : 1000} ]} ]

表的原地演变之分区演变

新增分区
        // 3.以day()方法新增分区spark.sql("ALTER TABLE local.iceberg_db.table2 ADD PARTITION FIELD day(ts)");// 4.新增数据spark.sql("INSERT INTO local.iceberg_db.table2 VALUES (4, 'd', cast(1727605185 as timestamp)),(5, 'e', cast(1725963585 as timestamp)),(6, 'f', cast(1726827585 as timestamp))");
文件关系变化图
数据层
元数据层
catalog
ts_month=2024-09
ts_month=2024-08
ts_day=2024-09-10
ts_day=2024-09-20
ts_day=2024-09-29
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table2

v3.metadata.jsonpartition-specs的变化,default-spec-id采用了新的分区组合spec-id1

  "default-spec-id" : 1,"partition-specs" : [ {"spec-id" : 0,"fields" : [ {"name" : "ts_month","transform" : "month","source-id" : 3,"field-id" : 1000} ]}, {"spec-id" : 1,"fields" : [ {"name" : "ts_month","transform" : "month","source-id" : 3,"field-id" : 1000}, {"name" : "ts_day","transform" : "day","source-id" : 3,"field-id" : 1001} ]} ]

可以发现:

  1. v3.metadata.json发现分区演变是一种元数据操作,并不急于重写文件。
  2. 表分区可以在现有表中更新
  3. 多个分区的共同存在。
删除分区
        spark.sql("ALTER TABLE local.iceberg_db.table2 DROP PARTITION FIELD month(ts)");
数据层
元数据层
catalog
ts_month=2024-09
ts_month=2024-08
ts_day=2024-09-10
ts_day=2024-09-20
ts_day=2024-09-29
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
v5.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table2

v5.metadata.jsonpartition-specs的变化,default-spec-id采用了新的分区组合spec-id2

  "default-spec-id" : 2,"partition-specs" : [ {"spec-id" : 0,"fields" : [ {"name" : "ts_month","transform" : "month","source-id" : 3,"field-id" : 1000} ]}, {"spec-id" : 1,"fields" : [ {"name" : "ts_month","transform" : "month","source-id" : 3,"field-id" : 1000}, {"name" : "ts_day","transform" : "day","source-id" : 3,"field-id" : 1001} ]}, {"spec-id" : 2,"fields" : [ {"name" : "ts_day","transform" : "day","source-id" : 3,"field-id" : 1001} ]} ]
删除数据
        spark.sql("DELETE FROM local.iceberg_db.table2  where id in (2)");
文件关系变化图
数据层
元数据层
catalog
ts_month=2024-09
ts_month=2024-08
ts_day=2024-08-29
ts_day=2024-09-10
ts_day=2024-09-20
ts_day=2024-09-29
status=2
status=0
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
data files
parquet格式
v1.metadata.json
v2.metadata.json
v3.metadata.json
v4.metadata.json
v5.metadata.json
v6.metadata.json
Manifest list
avro格式
Manifest list
avro格式
Manifest list
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
Manifest file
avro格式
ceberg_db.table2

删除数据操作会触发数据文件的变化,此时目录ts_day=2024-08-29已经于ts_month=2024-08平级。ts_day=2024-08-29中的数据文件会保留删除之后的数据。

由于分区的变化后,旧的分区规则产生的数据文件发生了数据变化,会产生一个新清单文件(maifest file)中的,会对旧的数据文件进行索引,以上述为例,v6.metadata.json对应的清单列表文件(maifest list)中存储了一个清单文件(maifest file)即虚线框展示的,其中存储了两个datafile的引用,status=2代表删除,status=0代表文件已经存在。

小结

  • 每一个操作都会产生一个新的元数据文件(metadata.json),需要配置自动清理元数据文件
  • 所有一个文件都伴有一个.crc文件,小文件的问题怎么办?
  • Iceberg使用唯一的id来跟踪表中的每一列。添加列时,将为其分配一个新ID,以便不会错误地使用现有数据。
  • 分区演变时,是元数据的操作,数据文件的操作是滞后的,有数据变动时才会进行文件的重写。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1551500.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp学习(003-1 vue3学习 Part.1)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第11p-第p14的内容 文章目录 vue3使用介绍插值表达式例子时间戳随机数输出函数的值 ref响应式数据变量v-bind 绑…

Python入门:深入了解__init__.py 文件(如何实现动态导入子模块)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 `__init__.py` 的作用示例:📝 如何编写 `__init__.py`1. 空的 `__init__.py`2. 导入子模块3. 初始化代码4. 动态导入子模块📝 编写 `__init__.py` 的技巧和注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 在…

大数据-155 Apache Druid 架构与原理详解 数据存储 索引服务 压缩机制

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

永不失联!遨游双卫星三防手机成为高效应急关键所在

今年9月被戏称为“台风月”&#xff0c;台风“摩羯”、“贝碧嘉”以及热带气旋“普拉桑”接连来袭&#xff0c;极端天气不仅导致了电力中断、道路损毁&#xff0c;更使得传统的通信网络遭受重创&#xff0c;给应急通信保障工作带来了极大的压力。面对“三断”的实战难题&#x…

Web3 游戏周报(9.22 - 9.28)

回顾上周的区块链游戏概况&#xff0c;查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【9.22-9.28】Web3 游戏行业动态&#xff1a; Axie Infinity 将 Fortune Slips 的冷却时间缩短至 24 小时&#xff0c;从而提高玩家的收入。 Web3 游戏开发商 Darkbright Studios…

SV830C产品介绍

SV830C产品介绍 SV830C是一款由珠海亿智科技有限公司&#xff08;Zhuhai Eeasy Technology Co., Ltd.&#xff0c;品牌名为EEASYTECH&#xff09;倾力打造的专业AI系统级芯片&#xff08;SoC&#xff09;&#xff0c;专为视频编码产品而设计。这款芯片不仅集成了先进的神经网络…

了解客户支持的人工智能:人工智能如何改变客户服务

作者&#xff1a;来自 Elastic Elastic Platform Team 我们都经历过这种情况&#xff1a;走进商店时&#xff0c;看到人工收银台排着长队&#xff0c;而所有自助收银台都是空的。这就是所谓的便捷工具并不那么便捷的情况。曾经&#xff0c;许多客户服务 “解决方案” 也处于这种…

局部整体(七)利用python绘制圆形嵌套图

局部整体&#xff08;七&#xff09;利用python绘制圆形嵌套图 圆形嵌套图&#xff08; Circular Packing&#xff09;简介 将一组组圆形互相嵌套起来&#xff0c;以显示数据的层次关系&#xff0c;类似于矩形树图。数据集中每个实体都由一个圆表示&#xff0c;圆圈大小与其代…

如何选择合适的跨境网络专线?

选择合适的跨境网络专线对于保障企业的国际业务顺畅运行至关重要。以下是一些选择跨境网络专线时可以参考的关键点&#xff1a; 服务商的信誉和经验&#xff1a;首先考察服务商的市场声誉和行业经验。一个好的服务商应该拥有良好的客户评价和成功案例&#xff0c;这表明他们有能…

掌握自动化测试必要的几种技能?

1.自动化测试员技能——编程语言 当我开始担任手动测试人员时&#xff0c;我不喜欢编码。但是&#xff0c;当我逐渐进入自动化领域时&#xff0c;对我来说很清楚&#xff0c;如果没有对编程语言的一些基本了解&#xff0c;就无法编写逻辑自动化测试脚本。 对编程有一点了解&a…

记录|Modbus-TCP产品使用记录【德克威尔】

目录 前言一、德克威尔1.1 实验图1.2 DECOWELL IO Tester 软件1.3 读写设置1.4 C#进行Modbus-TCP读写 更新时间 前言 参考文章&#xff1a; 使用的第二款Modbus-TCP产品。 一、德克威尔 1.1 实验图 1.2 DECOWELL IO Tester 软件 这也是自带模块配置软件的。下图就是德克威尔的…

nlp任务之预测中间词-huggingface

目录 1.加载编码器 1.1编码试算 2.加载数据集 3.数据集处理 3.1 map映射&#xff1a;只对数据集中的sentence数据进行编码 3.2用filter()过滤 单词太少的句子过滤掉 3.3截断句子 4.创建数据加载器Dataloader 5. 下游任务模型 6.测试预测代码 7.训练代码 8.保…

Solidworks斜接法兰快速绘制钣金箱体

Solidworks斜接法兰快速绘制钣金箱体 Chapter1 Solidworks斜接法兰快速绘制钣金箱体 Chapter1 Solidworks斜接法兰快速绘制钣金箱体 0.5mm间距为钣金焊接的预留焊缝。

高标准农田灌区信息化:为农业可持续发展注入新动力

高标准农田灌区信息化&#xff0c;作为现代农业科技与信息技术深度融合的典范&#xff0c;正逐步成为推动农业可持续发展的关键力量。这一创新模式不仅提升了农业生产效率与资源利用率&#xff0c;还为保障国家粮食安全、促进农村经济转型升级以及实现环境友好型农业开辟了新路…

基于Springboot+Vue的视频点播系统设计与实现登录 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统中…

小程序原生-数据的双向绑定

1. 通过model:实现数据的双向绑定 <input type"text" name"名称" model:value"{{name}}" /> <checkbox model:checked"{{isChecked}}"/> 是否同意该协议// pages/test/test.js Page({data: {name:wuk,isChecked:false}, }…

黑马头条day9 热点文章定时文章

bug 调度失败 刚开始以为是进程端口被占用了 Address already in use: bind【解决办法】-CSDN博客 ①先查询出占用端口的进程号 netstat -ano|findstr 8010②杀死该进程号的进程 taskkill -f -pid 21320发现关掉端口还是不行 解决了跨域问题也不行 解决办法 给的官方里…

png图片怎么转换成jpg?5个软件帮助你快速进行图片的格式转换

png图片怎么转换成jpg&#xff1f;5个软件帮助你快速进行图片的格式转换 将 PNG 图片转换为 JPG 是一种常见的需求&#xff0c;特别是当你需要减小图片文件大小或在不支持 PNG 格式的环境中使用时。以下五款软件能帮助你快速、简单地完成图片格式的转换&#xff0c;它们功能齐…

可以白嫖PPT模板的6个网站,赶紧收藏

推荐6个PPT模板网站&#xff0c;免费下载&#xff0c;绝对的高质量&#xff0c;赶紧收藏&#xff01; 1、菜鸟图库 ppt模板免费下载|ppt背景图片 - 菜鸟图库 菜鸟图库网有非常丰富的免费素材&#xff0c;像设计类、办公类、自媒体类等素材都很丰富。PPT模板种类很多&#xff0…

H5公众号调用微信扫一扫功能(vue)

1.引入微信sdk import wx from weixin-js-sdk 2.初始化微信sdk,构建扫一扫所需要的参数 async initWxConfig() { //首先获取当前url地址 let url await getSignUrl() let params { appid: this.$route.query.appid, url: url, } //调用后端接口获取公众号参数 const resp a…