hadoopnewcomer 发表于 2015-6-24 09:46:50

HDFS split大小

我想问一下:加入我在本地上传了三个小文件到HDFS 中,三个小文件的大小总和小于一个系统默认split的大小,这时候会形成三个MapTask呢还是说仍然是每个小文件一个Maptask?

xuanxufeng 发表于 2015-6-24 11:00:07

楼主说的是啥意思?
三个小文件上传跟mapreduce没有关系的。
上传是上传到hdfs.使用shell或则hdfsapi即可
参考hadoop实战:Java对hdfs的编程

Hadoop培训笔记之HDFS编程

hadoopnewcomer 发表于 2015-6-24 11:19:39

xuanxufeng 发表于 2015-6-24 11:00
楼主说的是啥意思?
三个小文件上传跟mapreduce没有关系的。
上传是上传到hdfs.使用shell或则hdfsapi即 ...

确实没啥关系啊.我用的是eclipse上传的.然后想对这三个文件中的单词建立倒排索引.要求不仅指出每个单词出现的次数还要指出在哪个文件中的次数.本以为在特定的目录下上传了三个小文件,会建立三个MapTask,这样在输出之后能看到每个文件对应的次数(中间通过split.getPath().toString()得到输入文件名,其中split是FileSplit对象).本以为会如愿得到单词:文件名:出现次数这样的形式,没想到最后得到的结果中文件名统一都是hdfs.所以我想问HDFS是不少把我上传的三个小文件合成一个文件作为输入文件呢?我代码是参看的刘鹏的那本<<实战hadoop>>p79的代码

bob007 发表于 2015-6-24 12:24:03

hadoopnewcomer 发表于 2015-6-24 11:19
确实没啥关系啊.我用的是eclipse上传的.然后想对这三个文件中的单词建立倒排索引.要求不仅指出每个单词出 ...


楼主看下这个程序应该就明了了,虽然版本比较旧,但是足以说明问题
public class TestwithMultipleOutputs extends Configured implements Tool {

  public static class MapClass extends Mapper<LongWritable,Text,Text,IntWritable> {

    private MultipleOutputs<Text,IntWritable> mos;

    protected void setup(Context context) throws IOException,InterruptedException {
      mos = new MultipleOutputs<Text,IntWritable>(context);
    }

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException{
      String line = value.toString();
      String[] tokens = line.split("-");

      mos.write("MOSInt",new Text(tokens), new IntWritable(Integer.parseInt(tokens)));//(第一处)
      mos.write("MOSText", new Text(tokens),tokens);     //(第二处)
      mos.write("MOSText", new Text(tokens),line,tokens+"/");  //(第三处)同时也可写到指定的文件或文件夹中
    }

    protected void cleanup(Context context) throws IOException,InterruptedException {
      mos.close();
    }

  }
  public int run(String[] args) throws Exception {

    Configuration conf = getConf();

    Job job = new Job(conf,"word count with MultipleOutputs");

    job.setJarByClass(TestwithMultipleOutputs.class);

    Path in = new Path(args);
    Path out = new Path(args);

    FileInputFormat.setInputPaths(job, in);
    FileOutputFormat.setOutputPath(job, out);

    job.setMapperClass(MapClass.class);
    job.setNumReduceTasks(0);  

    MultipleOutputs.addNamedOutput(job,"MOSInt",TextOutputFormat.class,Text.class,IntWritable.class);
    MultipleOutputs.addNamedOutput(job,"MOSText",TextOutputFormat.class,Text.class,Text.class);

    System.exit(job.waitForCompletion(true)?0:1);
    return 0;
  }

  public static void main(String[] args) throws Exception {

    int res = ToolRunner.run(new Configuration(), new TestwithMultipleOutputs(), args);
    System.exit(res);
  }

}



测试的数据:

abc-1232-hdf
abc-123-rtd
ioj-234-grjth
ntg-653-sdgfvd
kju-876-btyun
bhm-530-bhyt
hfter-45642-bhgf
bgrfg-8956-fmgh
jnhdf-8734-adfbgf
ntg-68763-nfhsdf
ntg-98634-dehuy
hfter-84567-drhuk

结果截图:(结果输出到/test/testMOSout)




然后:
对于不同的路径,hadoop可以对应不同的map。

不同路径的文件,楼主可以对里面的内容做一个标记。
输出到不同的路径中。
MultipleInputs可以加载不同路径的输入文件,并且每个路径可用不同的maper
MultipleInputs.addInputPath(job, new Path("hdfs://RS5-112:9000/cs/path1"), TextInputFormat.class,MultiTypeFileInput1Mapper.class);

MultipleInputs.addInputPath(job, new Path("hdfs://RS5-112:9000/cs/path3"), TextInputFormat.class,MultiTypeFileInput3Mapper.class);






evababy 发表于 2015-6-24 13:38:44

1、block是按对单个文件大小进行计算的
2、一个block占用一个map task

你上传三个文件,系统不会给你自动合并成一个,可以通过MultipleInputs.addInputPath方式读取多个文件并生成到一个文件中
注释楼上的job.setNumReduceTasks(0); 写合并reduce就可以了
页: [1]
查看完整版本: HDFS split大小