What is Hudi?
Hudi是Hadoop Upserts anD Incrementals的缩写,用于管理HDFS上的大型分析数据集存储。 Hudi的主要目的是高效的减少入库延时。 Hudi是Uber开发的一个开源项目。存储于HDFS上的分析数据集一般通过两种类型的表来提供,即读取优化的表(Read Optimized Table)和近实时表(Near-Realtime Table)。
Read Optimized Table的首要目的是通过列式存储来提升查询性能,而近实时表提供近乎实时的查询(基于行储和列储的组合)。
Hudi是一个开源Spark三方库,支持在Hadoop上执行upserts/insert/delete
操作。Hudu允许用户只获取已更改的增量数据,从而提高查询效率。Hudi可以像任何作业一样进行水平扩展,并直接在HDFS上存储数据。
接下来我们看下Hudi与时下几个热门系统的简单对比。
Hudi v.s. Kudu
两者是目的极为相似的存储系统,即通过对upserts
的一流支持来提供对PB级数据的实时分析。其中一个主要的区别是,Kudu还尝试充当OLTP场景下的数据存储区,但这是Hudi所不希望的。所以Kudu不支持增量拉取(Incremental Pulling)(截至2017年初),Hoodie这样做的目的是赋能数据增量处理的场景用例。
Kudu剥离了HDFS(Hadoop Distribute File System)及其分布式文件系统抽象接口,通过RAFT一致性算法管理自己的一组存储服务器。然而Hudi并没有使用这么”不友好“的设计,它自身不带底层存储集群,而是依赖Apache Spark做到与HDFS及一众Hadoop兼容的文件系统,如S3、Ceph等等。得益于此,Hudi可以想其他通用的Spark作业一样易扩展。相对而言,Kudu则需要对应的底层硬件和运维支持,这对于HBase或者Vertica此类的数据存储来说是很典型的。
截止目前,尚没有一份官方的基准测试可以全面地评估两者的性能。Hoodie是基于Parquet的扩展存储,据CERN上的一份报告Performance comparison of different file formats and storage engines in the Hadoop ecosystem推测,Hoodie在入库的性能上是值得期待的。
Hudi v.s. Hive Transactions / ACID
Hive Transactions / ACID是另一种类似的尝试,它试图基于ORC文件格式实现读取时合并(merge-on-read
)的存储功能。 可想而知,这个功能一定与Hive重度的集成,并且要依赖LLAP等其他必要的特性。 与Hudi相比,Hive Transactions不不支持读时优化(Read-Optimized)存储和增量拉取(Incremental Pulling)。
在实现上,Hudi可获得Spark等处理框架的全部功能加持,而Hive Transactions却只能受限于Hive任务/查询来实现。根据Uber工程师的实际生产经验,与其他方法相比,将Hudi作为一个三方依赖库嵌入现有Spark管道要更加简单有效。除了Hive之外,Hudi也被设计用于像Presto / Spark这样的计算引擎。将来Hudi也计划支持出Parquet以外的其他文件格式。
Hudi v.s Hbase
虽然HBase是面向OLTP场景的键值存储(key-value store),典型的应用场景就是不断插入新的记录且不怎么修改。但由于本身运行于HDFS之上,用户往往倾向于在HBase做一些分析相关的业务。鉴于HBase经过大量写入优化,它支持开箱即用的亚秒级upsert,而Hive-on-HBase则允许用户查询该数据。但就分析类业务场景的实际性能而言,由于这类场景负载主要在读取上,像Parquet/ORC这样的混合列式存储格式轻松击败HBase。 Hudi打破了数据快速入库和基于该数据进行分析业务之间的壁障。从可操作性上来说,相比于Hbase需要管理一个含有大量Region Server的集群来满足分析性业务场景,而Hudi主需要一个三方依赖库就可以实现,可维护性和可扩展性更强。最后,和Hudi相比,HBase不支持增量处理原语,如commit times
,incremental pull
。
Hudi v.s. Stream Processing
Hudi的开发者常常面对的一个问题就是,Hudi能和流式处理系统扯上什么关系?一言以蔽之的话,Hudi做的事情就是将批处理(copy-on-write storage
)和流计算(merge-on-read storage
)作业整合,并将计算结果存储在Hadoop中。对于Spark应用程序,依靠其同意的DAG模型可以将融入了Hudi库与Spark/Spark Steaming作业天然整合。对于非Spark处理系统(例如:Flink,Hive),处理过程可以在各自的系统中完成,然后以Kafka Topics 或者HDFS中间文件的形式发送到Hudi表中。从相对抽象的维度上来说,数据处理管道只包含三个组件:source
, processing
和sink
,用户最终面向sink
运行查询以使用管道的结果。Hudi可以作为source
或sink
,前者读取存储在HDFS上的Hudi表,后者将数据写人存储于HDFS的Hudi表。流式处理保存的Hudi表,最终交给Presto/Spark SQL/Hive做查询。
围绕着增量处理(incremental processing)这个概念,Hudi还有更加高级的应用场景。Hudi可以应用在数据处理引擎的内部以提升批处理的性能,例如,Hudi可以用作处理DAG内的状态存储(StateStore,类似于Flink使用rocksDB的方式)。这目前还是Hudi项目的一个roadmap计划,名为Beam Runner。