I use AvroParquetInputFormat.该用例需要扫描多个输入目录,每个目录将包含具有一个架构的文件。由于 AvroParquetInputFormat 类无法处理多个输入模式,我通过静态创建多个虚拟类(如 MyAvroParquetInputFormat1、MyAvroParquetInputFormat2 等)创建了一个解决方法,其中每个类仅继承自 AvroParquetInputFormat。对于每个目录,我设置了一个不同的MyAvroParquetInputFormat并且有效(如果有更干净的方法来实现这一点,请告诉我)。
我目前的问题如下:
每个文件都有几百列,基于元数据,我为每个目录构建一个projectionSchema,以减少不必要的磁盘和网络IO。我在每个MyAvroParquetInputFormat类上使用静态setRequestProjection()方法。但是,由于是静态的,最后一个调用的 projectionSchema 用于从所有目录中读取数据,这不是必需的行为。
任何指向解决方法/解决方案的指针将不胜感激。
感谢和问候
MK
,如果您的 avro 架构是兼容的(有关架构兼容性的定义,请参阅 avro doc),您可以使用单个架构访问所有数据。在此基础上,还可以构造一个与所有模式兼容的镶木地板友好模式(无联合),以便您可以只使用该模式。
至于你采取的方法,据我所知,没有简单的方法可以做到这一点。您必须以某种方式扩展多输入功能,以便为每种输入格式分配不同的架构。多输入通过在作业配置中设置两个配置属性来工作:
mapreduce.input.multipleinputs.dir.formats //contains a comma separated list of InputFormat classes
mapreduce.input.multipleinputs.dir.mappers //contains a comma separated list of Mapper classes.
这两个列表的长度必须相同。这就是它变得棘手的地方。此信息在Hadoop代码中深入使用,以初始化映射器和输入格式,因此您应该在此处添加自己的代码。
作为替代方案,我建议您使用已经可用的工具之一进行投影,例如 hive。如果没有太多不同的架构,则可以编写一组简单的 hive 查询来为每个架构执行投影,之后可以使用单个映射器来处理数据或任何您想要的内容。