一文搞懂 Iceberg 的 branch 和 tags

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益:

  1. 了解大厂经验
  2. 拥有和大厂相匹配的技术等

希望看什么,评论或者私信告诉我!

一、背景

最近发现期待已久的 Iceberg 的 branch 和 tags 上线了,刚好可以用来恢复数据。

要知道在大数据场景下,数据版本管理面临三大挑战:

在 Apache Iceberg 中,如果没有分支(Branch)和标签(Tag)功能,可能会导致以下问题:

数据版本管理问题

  • 无法跟踪数据变更历史:Iceberg 使用快照(Snapshot)来记录表在特定时间点的状态,但如果没有分支和标签,用户只能通过快照 ID 来识别不同版本的数据。快照 ID 是自动生成的,缺乏直观性和可读性,很难记住和区分不同版本的快照所代表的具体数据状态,例如无法明确知道某个快照是对应数据更新后的哪个阶段,难以追溯数据的变更历史。
  • 难以管理数据版本:当需要对数据进行版本管理时,例如在数据湖中保存不同时间点的数据版本以便进行数据分析或数据恢复,没有分支和标签功能会变得非常困难。用户只能依赖于快照 ID 来区分不同的版本,而快照 ID 的数量可能会随着数据更新而不断增加,导致管理混乱,难以快速定位到特定版本的数据。

数据隔离问题

  • 无法进行隔离的数据实验:在机器学习、数据分析等领域,常常需要对数据进行实验,例如尝试不同的数据处理方法、训练不同的模型等。如果没有分支功能,这些实验可能会直接影响到主数据表,导致生产环境中的数据被误修改,进而影响到下游的分析工作负载。例如,数据科学家在主表上插入新的实验数据后,可能会导致生产环境中的数据分析结果出现偏差,无法准确反映真实情况。
  • 难以实现数据的隔离开发和测试:开发人员可能需要在不影响生产环境的情况下进行数据开发和测试。如果没有分支功能,开发人员只能在主表上进行操作,这可能会导致数据错误或数据丢失,进而影响到生产环境的稳定性和可靠性,要不然就需要构建测试表。

Iceberg通过类Git的分支/标签机制,将代码管理的成熟理念引入数据湖,实现ACID事务、隔离实验、精准回溯三位一体能力。

二、介绍

2.1 tag

Iceberg tag 实现方式跟 Git tag 是一样的逻辑,比如:

之前 Apache Iceberg 使用名为 "快照" 的概念来维护表在特定时间点的状态。每次写入操作(例如 UPDATE 或 DELETE)更改 Iceberg 表的当前状态时,都会创建一个新的快照来跟踪该版本的表,并将其标记为当前快照。这确保读取器始终为发出查询请求的客户端获取最新版本的表,现在可以扩展到包括表的标记和分支。

2.1.1 创建标签

标签是单个快照的不可变标志 ,它们指向特定的快照 ID。例如,假设您正在处理一个名为"employee"的 Iceberg 表,该表包含截至 6 月份的数据,并且您希望使用该表的特定版本来训练机器学习模型。在这种情况下,您可以创建一个标签,并在以后的模型训练工作中引用它。创建标签的语法如下所示。

arduino 复制代码
spark.sql("ALTER TABLE  employee CREATE TAG EOM_Jun_2023")

执行成功后,Iceberg 将基于此版本的表创建一个名为 EOM_Jun_2023 的命名引用。Iceberg 表的任何后续更改(例如,新数据被提取)都不会影响此这个 tag,因为它是单独维护的。

需要注意的是,iceberg 的 snapshot 会过期,过期之后 tag 就没有了,所有我们在创建 tag 的时候,需要设置保留时间。比如保留 30 天

arduino 复制代码
spark.sql("ALTER TABLE employee CREATE TAG EOM_June_2023 RETAIN 30DAYS ")

2.1.2 tag 的使用例子

比如我们往 employee 表中插入几条数据

scss 复制代码
spark.sql("INSERT INTO employees values (1, 'Harry', 'Software Engineer', 25000), (2, 'John', 'Marketing Ops', 17000)")

此时,我们给 employee 打一个保留 10 天的 tag

arduino 复制代码
spark.sql("ALTER TABLE employees CREATE TAG june_data RETAIN 10 DAYS")

然后再插入几条数据

然后我们再根据 tag 进行查询

scss 复制代码
spark.sql("SELECT * FROM glue.test.employees VERSION AS OF 'june_data'").toPandas()

2.2 branch

2.2.1 创建 branch

Iceberg branch 实现方式跟 Git 的分支是一样的逻辑,比如创建一个 branch ML_exp

arduino 复制代码
spark.sql("ALTER TABLE employee CREATE BRANCH ML_exp")

2.2.2 branch 的使用

创建 branch ML_exp

arduino 复制代码
spark.sql("ALTER TABLE employee CREATE BRANCH ML_exp")

这是这个新分支中表的内容当前的样子:

现在我们开始往表branch ML_exp里写数据

lua 复制代码
schema = spark.table("glue.test.employees").schema
data = [
    (6, "Troy", "CMO", 30000.0),
    (7, "Raine", "UX", 21000.0),
    (8, "Harry", "QA", 22000.0)
  ]
df = spark.createDataFrame(data, schema)

df.write.format("iceberg").mode("append").save("employees.branch_ML_exp")
//df.write.format("iceberg").option("branch", "ML_exp").mode("append").save("employees")

写完后,我们来查看一下 ML_exp 分支的数据

scss 复制代码
spark.sql("SELECT * FROM employees VERSION AS OF 'ML_exp'").toPandas()

可以看到新的数据以及已经存在的数据。

如果过我们查询原始表的数据。可以看到,记录保持完整,并且没有因为实验而改变!

当然我们也可以删除 branch

arduino 复制代码
spark.sql("ALTER TABLE employees DROP BRANCH ML_exp")

2.3 注意

Iceberg 支持在单个表进行分支和tag,,如果您希望实现多表分支和tag,并且希望可以像 mysql 的事务那样,要么都成功,要么都失败,那么你可以尝试一下 Nessie

三、总结

文章详细讲解了 Iceberg 的分支和标签功能,包括创建、使用和管理这些功能的方法。通过类 Git 的机制,Iceberg 能够有效管理数据版本,支持数据实验和开发测试的隔离。此外,文章还介绍了 Nessie 作为跨表事务管理的工具,适用于需要多表一致性的场景。

相关推荐
我是谁的程序员3 分钟前
Flutter iOS真机调试报错弹窗:不受信任的开发者
后端
蓝宝石Kaze4 分钟前
使用 Viper 读取配置文件
后端
aiopencode6 分钟前
Flutter 开发指南:安卓真机、虚拟机调试及 VS Code 开发环境搭建
后端
开心猴爷10 分钟前
M1搭建flutter环境+真机调试demo
后端
沐道PHP11 分钟前
Go Gin框架安装记录
后端
技术宝哥26 分钟前
解决 Spring Boot 启动报错:数据源配置引发的启动失败
spring boot·后端·mybatis
独立开阀者_FwtCoder30 分钟前
2025年,真心佩服的十大开源工具
前端·后端·面试
喵手30 分钟前
如何快速掌握 Java 反射之获取类的字段?
java·后端·java ee
AronTing33 分钟前
06- 服务网格实战:从 Istio 核心原理到微服务治理升级
java·后端·架构
风生水气36 分钟前
在supabase中实现关键词检索和语义检索
后端·搜索引擎