Delta Lake的竞争对手Hudi(Alpha版)

2022-07-21 13:43:10 浏览数 (1)

Delta Lake肯定不是第一个数据湖产品。对于存储这块,CarbonData也一直有雄心。不过今天我要重点讲讲Delta Lake 和Hudi的对比。因为Hudi我仅限于基本的浏览了写入和读取相关的代码,理解上算不得成熟,所以这篇文章我加了限定词Alpha版,后续可能会Alpha01....Beta,当然最后肯定是没有标记,那就表示我觉得我的理解差不多了,文章可能定型了。

Hudi核心设计就是为了支持upsert, 并且同delta 一样,使用HDFS 兼容系统而非像Kudu那样,自己依赖于自己的存储(磁盘)。所以一个很容易做出的选择是,Hudi也是用列式存储Parquet文件作为基础文件。不同于Delta完全使用Spark API来操作Parquet文件,Hudi使用了Hadoop InputFormat相关的扩展来直接操作Parquet文件。这意味着,Hudi可以更好的被其他的计算引擎整合。

前面我们讨论,Delta使用的是Write On Merge策略,也就是说,在写入的时候做数据的合并,这样对于读非常友好。Hudi野心更大点,将Write On Merge 和Read On Merge都支持了。Write On Merge 和Delta的不同点是,Delta是直接读取原始文件通过Spark的join计算产生新的结果集,而Hudi是读取就的结果集,然后更新对应的记录,然后写成新的结果集。并且,对于一条记录是不是存在,Hudi是通过类似布隆过滤器或者外置存储HBase来完成的,这点上我认为Hudi的实现更传统,而Delta则更简单粗暴些,但从实现复杂度和内存可控度而言,我个人认为delta略深一筹。 Write On Merge的策略,优化了读,但是加重了写的负担。在Delta里,如果你重写轻读,可能目前没有额外的策略供你选择。但是Hudi提供了Read On Merge策略给你。为了能够让数据快速写入,Hudi这次引入了一个新的存储格式Avro, 为行存。 然后通过后台的compaction将行存转化为列存,避免read开销过大。当然,Read开销肯定是避免不了了,因为他需要同时读取parquet和增量的avro文件,最后才能得到视图。

在Write/Read权衡上,Hudi覆盖更全面一些,但是随之而来的是复杂度,以及使得他更像一个Service Server。比如,我们不应该开启多个Hudi实例同时操作一张Read On Merge的表,这样会导致多个实例都进行compaction操作。这里额外引入的议题是,Hudi似乎没有一个有效的锁机制,类似delta的乐观锁,可以让多个Hudi实例得到协调。

另外一个很重要的事情是版本,Hudi提供增量视图,也就是说给定一个时间区段,我可以得到这个时间区段新增以及被更改的记录。然而,我没有办法回归到某个版本。在流式计算里,我们可能因为一个新的版本上线导致流式结果错误,这个时候我们需要回退到某个版本。版本的价值非常大,而Hudi似乎没有提供这个非常核心的功能。

总体而言,我认为Hudi从设计的角度是弱于Delta的,他解决了批流共享,增量读取等功能,并且提供了两种Write/Read权衡的模式,但是他缺乏诸如版本,事务锁等机制,而这些功能对于数据湖而言异常重要。我们只能说,Hudi最早的出发点仅仅是为了解决Upsert的问题。

0 人点赞