问题导读 1.什么是Hudi? 2.Hudi对HDFS可以实现哪些操作? 3.Hudi与其它组件对比有哪些特点? 前两天我们About云群大佬公司想了解Hudi ,并上线使用。Hudi 或许大家了解的比较少,这里给大家介绍下Hudi这个非常实用和有潜力的组件。 Hudi是在HDFS的基础上,对HDFS的管理和操作。支持在Hadoop上执行upserts/insert/delete操作。这里大家可能觉得比较抽象,那么它到底解决了哪些问题? Hudi解决了我们那些痛点 1.实时获取新增数据 你是否遇到过这样的问题,使用Sqoop获取Mysql日志或则数据,然后将新增数据迁移到Hive或则HDFS。对于新增的数据,有不少公司确实是这么做的,比较高级点的,通过Shell调用Sqoop迁移数据实现自动化,但是这里面有很多的坑和难点,相对来说工作量也不少,那么有没有更好的解决办法那?---Hudi可以解决。Hudi可以实时获取新数据。 2.实时查询、分析 对于HDFS数据,我们要查询数据,是需要使用MapReduce的,我们使用MapReduce查询,这几乎是让我们难以接受的,有没有近实时的方案,有没有更好的解决方案--Hudi。 什么是Hudi Apache Hudi代表Hadoop Upserts anD Incrementals,管理大型分析数据集在HDFS上的存储。Hudi的主要目的是高效减少摄取过程中的数据延迟。由Uber开发并开源,HDFS上的分析数据集通过两种类型的表提供服务:读优化表(Read Optimized Table)和近实时表(Near-Real-Time Table)。 读优化表的主要目的是通过列式存储提供查询性能,而近实时表则提供实时(基于行的存储和列式存储的组合)查询。 Hudi是一个开源Spark库(基于Spark2.x),用于在Hadoop上执行诸如更新,插入和删除之类的操作。它还允许用户仅摄取更改的数据,从而提高查询效率。它可以像任何作业一样进一步水平扩展,并将数据集直接存储在HDFS上。 Hudi的作用 上面还是比较抽象的话,接着我们来看下图,更形象的来了解Hudi
我们看到数据库、Kafka更改会传递到Hudi,Hudi提供了三个逻辑视图: 1.读优化视图 - 在纯列式存储上提供出色的查询性能,非常像parquet表。 2.增量视图 - 在数据集之上提供一个变更流并提供给下游的作业或ETL任务。 3.准实时的表 - 使用基于列存储(例如 Parquet + Avro)和行存储以提供对实时数据的查询 我们看到直接在HDFS上存储数据,是可以用于Presto和Spark等交互式SQL引擎。 Hudi机制 存储机制 hudi维护了一个时间轴,记录了在不同时刻对数据集进行的所有操作。 hudi拥有2种存储优化。 读优化(Copy On Write):在每次commit后都将最新的数据compaction成列式存储(parquet); 写优化(Merge On Read):对增量数据使用行式存储(avro),后台定期将它compaction成列式存储。 读数据 hudi维护着一个索引,以支持在记录key存在情况下,将新记录的key快速映射到对应的fileId。索引的实现是插件式的,默认是bloomFilter,也可以使用HBase。 hudi提供3种查询视图。 读优化视图:仅提供compaction后的列式存储的数据; 增量视图:仅提供一次compaction/commit前的增量数据; 实时视图:包括读优化的列式存储数据和写优化的行式存储数据。 更新数据 hudi写数据的时候需要指定PRECOMBINE_FIELD_OPT_KEY、RECORDKEY_FIELD_OPT_KEY和PARTITIONPATH_FIELD_OPT_KEY。 RECORDKEY_FIELD_OPT_KEY:每条记录的唯一id,支持多个字段; PRECOMBINE_FIELD_OPT_KEY:在数据合并的时候使用到,当 RECORDKEY_FIELD_OPT_KEY 相同时,默认取 PRECOMBINE_FIELD_OPT_KEY 属性配置的字段最大值所对应的行; PARTITIONPATH_FIELD_OPT_KEY:用于存放数据的分区字段。 hudi更新数据和插入数据很相似(写法几乎一样),更新数据时,会根据 RECORDKEY_FIELD_OPT_KEY、PRECOMBINE_FIELD_OPT_KEY 以及 PARTITIONPATH_FIELD_OPT_KEY三个字段对数据进行Merge。 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此类的数据存储来说是很典型的。 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 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。 Hudi源码 基于以上相信大家应该对Hudi有了一定的认识,下面是github源码,感兴趣可以学习。 https://github.com/apache/incubator-hudi#building-apache-hudi-from-source
参考: https://hudi.apache.org/quickstart.html https://blog.csdn.net/qq_37095882/article/details/103714548 https://www.jianshu.com/p/2147a9105f39 https://hudi.apache.org/quickstart.html https://www.cnblogs.com/kehanc/p/12153409.html