CIDR'23: Analyzing and Comparing Lakehouse Storage Systems

Analyzing and Comparing Lakehouse Storage Systems 发布于 CIDR’23。作者包括了 UCB, Stanford,还有著名的 Mesos / Spark 的作者 Matei 和他的导师 Ion Stoica。本文分析了 DataBricks、Hudi、Iceberg 几大系统的存储,并且划分了下面的几个问题:

  1. Coordinator transaction
  2. Store metadata
  3. Query Metadata
  4. Handle Update (CoW, MoR. etc…)

每个问题的选择都会带来一定的 trade-off,本文也用 LHBench ( https://github.com/lhbench/lhbench ) 来对比了这些 Lakehouse。

我们之前的博客可以见:

  1. https://blog.mwish.me/2023/03/19/Apache-Iceberg-and-changes-above-Hive/
  2. https://blog.mwish.me/2022/05/01/Delta-Lake-Lakehouse/

根据我们自己的理解和论文的理解,Lakehouse 虽然产品定义是一个商业概念,但是技术上,它总的来说是一个 Meta 层 — Storage 层的概念,Raynold Xin 有一个 Talk 的 PPT 做的很好,我就直接抠出来了:

img

这里可以看到,虽然 Lakehouse 是个商业概念,但是这些点还是比较清晰的:

  1. (对外)依赖 Open Format 和比较定义好的存储(比如 Object Store)
    1. Object Store and Lakehouse: High latency
    2. 对外: (weak) Consistency gurantee
  2. 一定程度上的数据 / 元数据处理. 支持一些简单的 ACID 语义(这块的 ACID 语义其实没有传统的关系型数据库定义的那么清晰)

知道这个概念之后我们再来看这篇论文提出的几个点:

  1. 如何协调事务。这里涉及读写 — 写写的关系。
    1. 上层事务永远下层的(对象)存储:有的地方如果考虑写 S3 或者对象存储当作事务,可能会考虑使用对象存储的 Put-if-absent 语义 (有的不支持的可能额外依赖一个外部系统)
    2. 用额外的存储系统,比如像 Hive MetaStore(或许还包括 FDB?). 相对来说,这里提交延迟(不考虑 LIST,那又是另一个问题了)会低一些,但本身也会这个系统有一定的影响
  2. 如何存储 metadata. (For Pruning, etc.)
    1. 把数据存到额外的表上(Google Bigmeta?)
    2. 放到 Transaction Log 上
    3. 放到额外的服务去(FDB?)
  3. 如何查询 Metadata
    1. Delta Lake 和 Hudi 可以用系统的 Parallel Job 来查询 Metadata,在大表的时候并行 Planing,加速,但这个对小表来说可能会增大 latency
    2. Iceberg 现在是单线程查询
    3. (但我理解这几个特么的都可以并行吧,标准在那人是活人)
  4. 如何高效处理 Record 级别的更新。这里因为 Lakehouse 本身处理大批数据,本身有很多批量加载数据的逻辑,比如 SQL Merge 这种。不同系统可能有 Copy-on-write 或者 Merge-on-read 等方式

论文里面还提到一些比较好玩的东西,很符合我的直觉

On the one hand, organizations use lakehouse systems to ingest and organize very large datasets—for example, the largest Delta Lake tables span well into the hundreds of petabytes, consist of billions of files, and are updated with hundreds of terabytes of ingested data per day [21]. On the other hand, the data warehouse capabilities of lakehouse systems are encouraging organizations to load and manage smaller datasets in them too, in order to combine these with the latest data from their ingest pipelines and build a single management system for all data. For example, most of the CPU-hours on Databricks are used to process tables smaller than 1 TB, and query durations across all tables range from sub-second to hours.

论文中对 Lakehouse 拆分剖析如下:

img

文章后面有一些 benchmark,但我觉得没啥意思,就不看了,你妈的这些 benchmark 比较在做过的人眼里完全没任何价值。

Transaction Coordination

  • 支持单表事务,但是对多标事务支持可能不是特别好,同事事务支持的语义不完全相同(见 Table1 的 Isolation Levels)
  • Delta Lake 使用对象存储的事务。对于 S3 这种不支持 conditional-write 的,Delta Lake 使用 Dynamo 来做协调(Lance 和 arrow-rs 的 object-store 也支持同样的语义)。我个人觉得,这套方案的本质是依赖事务性 CAS Logging 和 Lakehouse 本身的低提交频率(或者即使提交数据多,在他们的场景也倾向于是大 SQL作业提交大批量数据,而不是TP的高tps小事务)
  • Hudi/Iceberg HMS/Zk/Dynamo 实现的表锁。论文因为有 Delta 的人,还小小的抹黑了一下提到他们有因为这个造成脏写的问题(Hive: Fix concurrent transactions overwriting commits by adding hive lock heartbeats. https://github.com/apache/iceberg/pull/5036 )。但我觉得属于半尬黑了,本质原因还是依赖外部系统做一个存储层的 fencing 是比较难的,退一万步说,我觉得你 Delta 依赖 Dynamo 在 S3 上操作还比人家有优越感了么。当然依赖少确实是有优势的就是了,本质也是 trade-off。

这几个产品本身都是用 OCC 的协议(insite: 冲突可能会比较小?),但是提供了不同的语义(又要开始吹自己了):

  • Iceberg 和 Hudi 都会保证读的时候来自 start snapshot,提交的时候和已经提交的事务没有写写冲突,所以这块的隔离级别是 SI
  • Delta 默认会保证(当然 Iceberg 也有这个能力)更新的时候没有 SI会遇到的 anti-dependency ( https://blog.mwish.me/2020/11/14/%E4%BA%8B%E5%8A%A1-%E5%8D%8F%E8%AE%AE%E5%92%8C%E9%9A%94%E7%A6%BB/ 比如只剩一个用户,然后两个事务都是 `IF(exist) then -1 and …`` 这种,用这种方式来支持 Serializable(当然这块读可能不完全按照定义,一个读仍然可能读到不满足时序的数据)。Delta 甚至可以开启读的时候也做检查的限制,来达到 Strict Serializable

Metadata Management

S3 之类的 LIST 本身限制 1000 个文件,LIST 一个大目录延迟高,可能还要手写循环或者递归,还是比较菜的。为了突破这种限制,几个 Lakehouse 都支持把 Metadata 外存,论文这里把外存分成了 Tabular 和 Hierachical 两种方式:

  • Delta Lake 和 Hudi 把元数据存储在 metadata table(Hudi) , Transaction Log Checkpoint(Delta 存储 JSON / Parquet )。这两种系统元数据提交是直接写日志然后周期性 Merge-On-Read 合并到表中(本质上有点像 Lakehouse 搞从 CDC 中导入数据的 Pattern?)
  • Iceberg 直接存成层次的文件

Data Update Strategies

分为 COW 和 MOR。但是根据我个人的观察,比较困难的其实还是更新 / 宽表更新单列 这类的处理,有的地方可能会写 opLog,有的地方会产生一个 Primary Key 然后覆盖 PK,有的地方会更新宽表的时候 CoW 单列。

Reference

  1. https://www.montecarlodata.com/impact-2021-the-data-lakehouse/ Reynold Xin 在 21 年的 Talk。我觉得先看这个再看 VLDB的 LakeHouse Paper 比较好,毕竟主创自己的意思肯定更清晰一些