前言
补充上一篇文章Hudi Spark源码学习总结-spark.read.format(“hudi”).load,由于上篇文章篇幅已经比较长了,所以单独写一篇补充一下,没有读过的可以先阅读一下,我们在上篇文章讲到resolveBaseFileOnlyRelation返回的是HadoopFsRelation,那么如果返回BaseFileOnlyRelation呢?
起因
其实除了HadoopFsRelation、BaseFileOnlyRelation还有IncrementalRelation、MergeOnReadSnapshotRelation、MergeOnReadIncrementalRelation、HoodieBootstrapRelation,之所有要单独看一下BaseFileOnlyRelation,是因为我们从提交历史上可以看出,一开始默认的就是HadoopFsRelation后来添加了自定义的BaseFileOnlyRelation,然后现在回退成了HadoopFsRelation,查看对应PR了解了一下原因
添加BaseFileOnlyRelation的PR:[HUDI-3338] custom relation instead of HadoopFsRelation,原因是:目前,HadoopFsRelation将使用实际分区路径的值作为分区字段的值。但是,与普通表不同,Hudi在Parquet文件中保留分区值。在某些情况下,实际分区路径的值和分区字段的值是不同的。因此,这里实现了BaseFileOnlyViewRelation,通过它,Hudi可以管理自己的关系。
回退为HadoopFsRelation的PR:[HUDI-3902] Fallback to HadoopFsRelation in cases non-involving Schema Evolution,原因是:Spark的一些优化规则(以及一些其他处理)是基于HadoopFsRelation的使用,这导致当我们依赖自定义Relation时,这些优化没有得到应用。我们可以在[HUDI-3338]的PR的下面可以看到,有commiter提出,使用BaseFileOnlyRelation后查询性能相比于之前的HadoopFsRelation下降了大约一倍,这是因为Spark仅在少数地方做了查询优化,其中一个地方就是我们在上篇文章中讲到的FileSourceStrategy,我们看到[HUDI-3902]虽然回退到HadoopFsRelation,但是貌似并没有处理分区路径值的问题,所以后面又提了一个PR:
PR:[HUDI-3204] Fixing partition-values being derived from partition-path instead of source columns,这个PR添加了自定义FileFormat:Spark24HoodieParquetFileFormat,它重写了ParquetFileFormat的buildReaderWithPartitionValues方法。其中的关键点是添加了参数shouldAppendPartitionValues来判断是否将分区路径中的值添加为分区字段的值。
1 | if (shouldAppendPartitionValues) { |