MapReduce作业的多个输入

时间:2014-10-21 14:07:45

标签: hadoop mapreduce

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

例如,使用配置属性

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

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

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

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

例如,假设我输入了两个文件," source1.txt"和" source2.txt"。我可以编写像

这样的配置
source1.separator=,
source1.id=2
...
source2.separator=|
source2.id=4
...

映射器将从拆分中获取文件名,然后使用相同的前缀读取配置属性。

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

2 个答案:

答案 0 :(得分:0)

我已经解决了。事实证明,维护了将输入源(文件或目录)添加到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中将作业输入源添加到作业的顺序。

答案 1 :(得分:0)

我不确定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);

对于每种文件类型,您必须提供所需的正则表达式。希望你擅长它。