最近发现期待已久的 Iceberg 的 branch 和 tags 上线了,刚好可以用来恢复数据。
要知道在大数据场景下,数据版本管理面临三大挑战:
在 Apache Iceberg 中,如果没有分支(Branch)和标签(Tag)功能,可能会导致以下问题:
Iceberg通过类Git的分支/标签机制,将代码管理的成熟理念引入数据湖,实现ACID事务、隔离实验、精准回溯三位一体能力。
Iceberg tag 实现方式跟 Git tag 是一样的逻辑,比如:
之前 Apache Iceberg 使用名为 “快照” 的概念来维护表在特定时间点的状态。每次写入操作(例如 UPDATE 或 DELETE)更改 Iceberg 表的当前状态时,都会创建一个新的快照来跟踪该版本的表,并将其标记为当前快照。这确保读取器始终为发出查询请求的客户端获取最新版本的表,现在可以扩展到包括表的标记和分支。
标签是单个快照的不可变标志 ,它们指向特定的快照 ID。例如,假设您正在处理一个名为“employee”的 Iceberg 表,该表包含截至 6 月份的数据,并且您希望使用该表的特定版本来训练机器学习模型。在这种情况下,您可以创建一个标签,并在以后的模型训练工作中引用它。创建标签的语法如下所示。
spark.sql("ALTER TABLE employee CREATE TAG EOM_Jun_2023")
执行成功后,Iceberg 将基于此版本的表创建一个名为 EOM_Jun_2023 的命名引用。Iceberg 表的任何后续更改(例如,新数据被提取)都不会影响此这个 tag,因为它是单独维护的。
需要注意的是,iceberg 的 snapshot 会过期,过期之后 tag 就没有了,所有我们在创建 tag 的时候,需要设置保留时间。比如保留 30 天
spark.sql("ALTER TABLE employee CREATE TAG EOM_June_2023 RETAIN 30DAYS ")
比如我们往 employee 表中插入几条数据
spark.sql("INSERT INTO employees values (1, 'Harry', 'Software Engineer', 25000), (2, 'John', 'Marketing Ops', 17000)")
此时,我们给 employee 打一个保留 10 天的 tag
spark.sql("ALTER TABLE employees CREATE TAG june_data RETAIN 10 DAYS")
然后再插入几条数据
然后我们再根据 tag 进行查询
spark.sql("SELECT * FROM glue.test.employees VERSION AS OF 'june_data'").toPandas()
Iceberg branch 实现方式跟 Git 的分支是一样的逻辑,比如创建一个 branch ML_exp
spark.sql("ALTER TABLE employee CREATE BRANCH ML_exp")
创建 branch ML_exp
spark.sql("ALTER TABLE employee CREATE BRANCH ML_exp")
这是这个新分支中表的内容当前的样子:
现在我们开始往表branch ML_exp里写数据
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 分支的数据
spark.sql("SELECT * FROM employees VERSION AS OF 'ML_exp'").toPandas()
可以看到新的数据以及已经存在的数据。
如果过我们查询原始表的数据。可以看到,记录保持完整,并且没有因为实验而改变!
当然我们也可以删除 branch
spark.sql("ALTER TABLE employees DROP BRANCH ML_exp")
Iceberg 支持在单个表进行分支和tag,,如果您希望实现多表分支和tag,并且希望可以像 mysql 的事务那样,要么都成功,要么都失败,那么你可以尝试一下 Nessie
文章详细讲解了 Iceberg 的分支和标签功能,包括创建、使用和管理这些功能的方法。通过类 Git 的机制,Iceberg 能够有效管理数据版本,支持数据实验和开发测试的隔离。此外,文章还介绍了 Nessie 作为跨表事务管理的工具,适用于需要多表一致性的场景。