乐趣区

关于数据湖:读Paimon源码聊设计引子

最近我司开始摸索 Paimon 在局部场景下的应用,因而我这边须要做一些技术储备,缓缓关注起来 Paimon 的一些实现细节。

简略介绍一下前辈 Iceberg

个别的数据湖都会设计成凋谢通用的,即不和特定的存储、计算引擎(比方 Spark 和 Flink)绑定。所以数据湖的定位是在计算引擎之下,又在存储之上,将其称之为 table format。须要强调的是数据湖个别是面向 OLAP 场景的,所以个别存储会抉择分布式文件系统。当初 OLAP 底层存储反对对象存储根本算是快成业界共识了,这玩意儿挺划算的。

数据湖的前辈根本就是 Hive 了。过后大家用 Hive 碰到的问题就是 Hive 耦合 HDFS 很厉害,最次要体现在:

  1. Hive 上的计算执行首先依赖于 list 操作。在对象存储上做 list 是个很慢的操作。
  2. Hive 的写数据依赖于 rename。但同样这个操作在对象存储上做特地的慢。

这两个问题间接导致无奈降本。从这点上来说,Iceberg 是本人保护了一套元数据,这块网上十分的全,就不再赘述了,google 上搜 iceberg file layout 一大把。

Hive 还有其余的问题,如:

  1. metastore 的瓶颈问题。
  2. 没有 ACID 保障。
  3. parition 字段必须显示的在 query 里。
  4. 下推能力无限。Hive 只能通过 partition 和 bucket 对须要扫描哪些文件进行过滤,无奈更加粗疏。只管 parquet 文件里保留了 max 和 min 值能够用于进一步的过滤,但没软用。

Iceberg 把这些都解了。基于快照实现事务、数据的更新,快照的数据也容许跳版本读取来做工夫回溯。同时收集的统计信息也更加细粒度,不仅仅是文件 parition 级别的,还会记录文件级的内容(比方一个文件中的 min、max 值)和实现文件内容级的信息——一个文件中的 min、max 等等。

听起来所有都还很美妙。惟一美中不足的就是 Iceberg 对于实时场景反对得不好:

  • Flink 写入 Iceberg 会引发小文件的问题。
  • Iceberg 不反对 CDC(OLAP 反对 CDC 确实有点离谱,然而确实有需要呀)。
  • Iceberg 主键表不反对局部字段更新。这在实时数仓的场景中有点离谱。

Paimon 能够解决什么问题

目前看来 Paimon 基于 Iceberg 的场景上,去反对流读流写(这块后续会做源码剖析),甚至还反对了点查和预聚合。实质是分布式文件系统上套了一个 LSM,这样数据都是有序写入——将屡次写入优化成一次程序写入,对存储系统上比拟敌对的。同时 LSM 能够作为一个简略的缓存,且有序写入为前面查问也能够缩小代价,这都能够为查问缩小代价。

从场景上来说它能够解决一些准实时业务的场景。因为基于对象存储来做底层存储,尤其还是列式存储。无论如何都不好做到实时场景:

  • Paimon 的 CDC 依据不同的模式,会有不同的新鲜度。收回残缺 CDC 的模式要抉择 Lookup。个别是 Checkpoint 的距离 +10s 多新鲜度,这是比拟好的性能考量下。具体还要看数据量、分桶数、小文件数量的影响。
  • 实时场景要求是毫秒级点查响应。Paimon 反对的是秒级点查。

但事实中真正须要实时类场景的业务有多少呢?因为数据的新鲜度往往和业务决策周期有关系。这么来看,数据新鲜度的要求从高到低,对于业务场景的总数来说,肯定是一个金字塔形态的。

咱们后面提到过数据湖个别不会和任何计算引擎绑定。因而业界还有一种玩法叫湖上建仓,计算能力用的是 OLAP,数据来自数据湖。这样就很有想象力了,因而当初一些实时 + 离线的场景会用不同的存储引擎,那么数据就会拷贝好几份。如果数据都放在同一个数据引擎中,这样能够缩小不少的存储老本。(对于通用型设计 这块后续会做源码剖析

具体实现还是看对于性能的要求的:

  • 要求低就做一些简略的优化间接捞数据。
  • 再高点就缓存到 OLAP 里。
  • 再高点就不仅仅是缓存到 OLAP 里,还会做物化视图。

Trade Off

Serving、Trascantion、Analytics

依据业界常识,咱们会发现:

  • 面向在线利用,高并发、疾速、简略,如:HBase、Redis
  • 面向剖析的,大规模数据扫描、过滤、汇总,如:Hive、Presto
  • 面向事务、随机读写的,如:MySQL,PostgreSQL

数据湖是典型的 OLAP 产物。但联合上文,它确实具备肯定的随机读写能力。

Buffer、Mutable、Ordered

存储构造有三个常见变量:是否应用缓冲、应用不可变的还是可变的文件,以及是否按顺序存储值(有序性)。

因为 TiDB 底层的 RocksDB 用了 LSM。因而应用了缓冲、不可变性以及程序性。

RUM

有一种风行的存储构造开销模型思考了如下三个因素:读取(Read)、更新(Update)和内存(Memory)开销。它被称为 RUM 猜测。

RUM 猜测指出,缩小其中两项开销将不可避免地导致第三项开销的好转,并且优化只能以就义三个参数中的一个为代价。咱们能够依据这三个参数对不同的存储引擎进行比拟,以理解它们针对哪些参数进行了优化,以及其中隐含着哪些可能的衡量。

一个现实的解决方案是领有最小的读取开销,同时放弃较低的内存与写入开销。但在事实中,这是无奈实现的,因而咱们须要进行取舍。

Paimon 容许在配置中自在设置 LSM 的高度,以便获取读与写之前的衡量。

底细鸟瞰

后面说到过,计算局部是依赖于计算引擎实现的,自身 Paimon 没有提供计算能力。存储则是基于局部是文件系统做了薄薄的一层 LSM。

从文件布局来看,Partition 相当于是一级索引,和 Hive 一样。Bucket 为二级索引,每个 Bucket 下都会有 Data file 和 Change log file。这意味着如果命中了 Parition 和 Bucket 条件,有一些额定的条件查问也不会太慢——个别都会收集文件级的统计信息,并对文件的 Reader 做一些过滤优化。

整体的布局还是和 Iceberg 挺像的,这边不再过多赘述。

小结

在这篇文章中我简略的介绍了一下 Paimon 要解决的问题,以及它的前辈 Iceberg 的弱小与不足之处。

目前该我的项目还处于孵化中,后续我会始终关注其实现细节,敬请期待。

退出移动版