首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >一文搞懂 Iceberg 的 branch 和 tags

一文搞懂 Iceberg 的 branch 和 tags

作者头像
shengjk1
发布2025-05-16 15:16:21
发布2025-05-16 15:16:21
15200
代码可运行
举报
文章被收录于专栏:码字搬砖码字搬砖
运行总次数:0
代码可运行

一、背景

最近发现期待已久的 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 月份的数据,并且您希望使用该表的特定版本来训练机器学习模型。在这种情况下,您可以创建一个标签,并在以后的模型训练工作中引用它。创建标签的语法如下所示。

代码语言:javascript
代码运行次数:0
运行
复制
spark.sql("ALTER TABLE  employee CREATE TAG EOM_Jun_2023")

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

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

代码语言:javascript
代码运行次数:0
运行
复制
spark.sql("ALTER TABLE employee CREATE TAG EOM_June_2023 RETAIN 30DAYS ")
2.1.2 tag 的使用例子

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

代码语言:javascript
代码运行次数:0
运行
复制
spark.sql("INSERT INTO employees values (1, 'Harry', 'Software Engineer', 25000), (2, 'John', 'Marketing Ops', 17000)")

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

代码语言:javascript
代码运行次数:0
运行
复制
spark.sql("ALTER TABLE employees CREATE TAG june_data RETAIN 10 DAYS")

然后再插入几条数据

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

代码语言:javascript
代码运行次数:0
运行
复制
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

代码语言:javascript
代码运行次数:0
运行
复制
spark.sql("ALTER TABLE employee CREATE BRANCH ML_exp")
2.2.2 branch 的使用

创建 branch ML_exp

代码语言:javascript
代码运行次数:0
运行
复制
spark.sql("ALTER TABLE employee CREATE BRANCH ML_exp")

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

image.png
image.png

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

代码语言:javascript
代码运行次数:0
运行
复制
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 分支的数据

代码语言:javascript
代码运行次数:0
运行
复制
spark.sql("SELECT * FROM employees VERSION AS OF 'ML_exp'").toPandas()
image.png
image.png

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

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

image.png
image.png

当然我们也可以删除 branch

代码语言:javascript
代码运行次数:0
运行
复制
spark.sql("ALTER TABLE employees DROP BRANCH ML_exp")

2.3 注意

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

三、总结

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、背景
    • 数据版本管理问题
    • 数据隔离问题
  • 二、介绍
  • 2.1 tag
    • 2.1.1 创建标签
    • 2.1.2 tag 的使用例子
  • 2.2 branch
    • 2.2.1 创建 branch
    • 2.2.2 branch 的使用
  • 2.3 注意
  • 三、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档