MapReduce作业的多个输入



我正在尝试编写一个MapReduce作业,该作业需要许多分隔的输入源。所有源都包含相同的信息,但信息可能位于不同的列中,并且每个源的分隔符可能不同。源在映射器中通过配置文件进行解析。此配置文件允许用户限制这些不同的分隔符和列映射。

例如,使用配置属性解析input1

input1.separator=,
input1.id=1
input1.housename=2
input1.age=15

其中1、2和15是input1中与这些属性相关的列。

因此,映射器需要知道要为每个输入源使用哪些配置属性。我不能硬编码,因为其他人将运行我的工作,并且希望在不需要编译器的情况下添加新的输入。

显而易见的解决方案是从拆分中提取文件名,并以这种方式应用配置。

例如,假设我正在输入两个文件,"source1.txt"one_answers"source2.txt"

source1.separator=,
source1.id=2
...
source2.separator=|
source2.id=4
...

映射程序将从拆分中获取文件名,然后读取具有相同前缀的配置属性。

但是,如果我指向Hive仓库中的文件夹,我就不能使用它。我可以提取一些路径并使用它们,但我真的觉得这不是一个优雅或坚固的解决方案。有更简单的方法吗?

我不确定MultipleInputs是否提供PathFilter集成。但是,您可以根据自己的条件扩展一个文件并将匹配的文件馈送到不同的Mapper类型。

FileStatus[] csvfiles = fileSystem.listStatus(new Path("hive/path"),
            new PathFilter() {
                public boolean accept(Path path) {
                    return (path.getName().matches(".*csv$"));
                }
            });

将处理映射器分配到此列表:

MultipleInputs.addInputPath(job, csvfiles[i].getPath(), 
                                 YourFormat.class, CsvMapper.class);

对于每种文件类型,您都必须提供所需的regex。希望你擅长。

我已经解决了这个问题。原来,输入源(文件或目录)添加到FileInputFormat的顺序得到了维护,然后作为mapreduce.input.fileinputformat.inputdir存储在作业上下文中。所以,我的解决方案

Runner.java

for(int i=X; i<ar.length; i++) {
    FileInputFormat.addInputPath(job, new Path(ar[i]));
}

其中X是可以找到输入路径的第一个整数。

InputMapper.java

#Get the name of the input source in the current mapper
Path filePath = ((FileSplit) context.getInputSplit()).getPath();
String filePathString = ((FileSplit) context.getInputSplit()).getPath().toString();
#Get the ordered list of all input sources
String pathMappings = context.getConfiguration()
    .get("mapreduce.input.fileinputformat.inputdir");

由于我知道将输入源添加到作业的顺序,因此我可以使用数字让用户设置配置属性,并在CLI中将数字映射到将输入源加入作业的顺序。

相关内容

  • 没有找到相关文章

最新更新