我在hadoop 2.9.0上运行Mapreduce。
我的问题:
我有许多文本文件(大约10-100个文本文件)。每个文件的大小都非常小,但由于我的逻辑问题,我需要 1个映射器来处理1个文本文件。这些映射器的结果将由我的reducer汇总。
我需要设计,以便映射器的数量始终等于文件的数量。如何在Java代码中执行此操作?我需要扩展什么样的功能?
非常感谢。
答案 0 :(得分:1)
我必须做一些非常相似的事情,并面临类似的问题。 我实现这一目标的方法是输入一个包含每个文件路径的文本文件,例如文本文件将包含这种信息:
/path/to/filea
/path/to/fileb
/a/different/path/to/filec
/a/different/path/to/another/called/filed
我不确定你想要你的映射器做什么,但是在创建你的工作时,你想要做以下事情:
public static void main( String args[] ) {
Job job = Job.getInstance(new Configuration(), 'My Map reduce application');
job.setJarByClass(Main.class);
job.setMapperClass(CustomMapper.class);
job.setInputFormatClass(NLineInputFormat.class);
...
}
您的CustomMapper.class
会像这样扩展Mapper:
public class CustomMapper extends Mapper<LongWritable, Text, <Reducer Key>, <Reducer Value> {
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
Configuration configuration = context.getConfiguration();
ObjectTool tool = new ObjectTool(configuration, new Path(value.toString()));
context.write(<reducer key>, <reducer value>);
}
}
ObjectTool
是另一个类,它处理您想要对文件实际执行的操作。
因此,让我广泛地解释一下这是做什么的,这里的魔力是job.setInputFormatClass(NLineInputFormat.class)
,但它到底在做什么呢?
它实际上是按照每行输入和分割数据,并将每一行发送到映射器。通过以新行包含每个文件的文本文件,然后在映射器和文件之间创建1:1关系。这个设置的一个很好的补充是它允许您为要处理的文件创建高级工具。
我用这个在HDFS中创建一个压缩工具,当我研究这个方法的时候,很多人基本上都是把文件读到stdout并以这种方式压缩它,但是,当它做一个校验和时原始文件和正在压缩和解压缩的文件,结果不同。这是由于这些文件中的数据类型,并且没有简单的方法来实现可写字节。 (可以看到有关标记文件的信息here)。
该链接还引用了以下内容:
org.apache.hadoop.mapred.lib.NLineInputFormat是这里的魔力。它基本上告诉作业每maptask提供一个文件
希望这有帮助!