Hadoop中的NLineInputFormat

一:背景

NLineInputFormat也是FileInputFormat的子类,它是根据行数来划分InputSplit的,而不是像TextInputFormat那样依赖分片大小和行的长度。也就是说,TextInputFormat当一行很长或分片很小时,获取的分片很可能只包含很少的K-V对,这样一个MapTask处理的K-V对就很少,这是不太理想的。因此我们可以使用NLineInputFormat来控制一个MapTask处理的K-V对,这是通过分割InputSplit时按行数分割的方法来实现的,关键是通过mapreduce.input.lineinputformat.linespermap来设置这个行数。

 

二:技术实现

代码如下:

 

[java]  view plain  copy
 
  1. /** 
  2.  * TextInputFormat处理的数据来自一个InputSplit,InputSplit是根据大小划分的。 
  3.  * NLineInputFormat可以决定每个Mapper处理的记录数是相同的。 
  4.  * @author 廖钟民 
  5.  * time : 2015年1月15日下午8:40:43 
  6.  * @version 
  7.  */  
  8. public class MyNLineInputFormat {  
  9.       
  10.     // 定义输入路径  
  11.         private static final String INPUT_PATH = "hdfs://liaozhongmin:9000/hello";  
  12.         // 定义输出路径  
  13.         private static final String OUT_PATH = "hdfs://liaozhongmin:9000/out";  
  14.   
  15.         public static void main(String[] args) {  
  16.   
  17.             try {  
  18.                 // 创建配置信息  
  19.                 Configuration conf = new Configuration();  
  20.                 //设置每个Map可以是处理多少条记录  
  21.                 conf.setInt("mapreduce.input.lineinputformat.linespermap", 2);  
  22.                 /**********************************************/  
  23.                 //对Map端输出进行压缩  
  24.                 //conf.setBoolean("mapred.compress.map.output", true);  
  25.                 //设置map端输出使用的压缩类  
  26.                 //conf.setClass("mapred.map.output.compression.codec", GzipCodec.class, CompressionCodec.class);  
  27.                 //对reduce端输出进行压缩  
  28.                 //conf.setBoolean("mapred.output.compress", true);  
  29.                 //设置reduce端输出使用的压缩类  
  30.                 //conf.setClass("mapred.output.compression.codec", GzipCodec.class, CompressionCodec.class);  
  31.                 // 添加配置文件(我们可以在编程的时候动态配置信息,而不需要手动去改变集群)  
  32.                 /* 
  33.                  * conf.addResource("classpath://hadoop/core-site.xml");  
  34.                  * conf.addResource("classpath://hadoop/hdfs-site.xml"); 
  35.                  * conf.addResource("classpath://hadoop/hdfs-site.xml"); 
  36.                  */  
  37.   
  38.                 // 创建文件系统  
  39.                 FileSystem fileSystem = FileSystem.get(new URI(OUT_PATH), conf);  
  40.                 // 如果输出目录存在,我们就删除  
  41.                 if (fileSystem.exists(new Path(OUT_PATH))) {  
  42.                     fileSystem.delete(new Path(OUT_PATH), true);  
  43.                 }  
  44.   
  45.                 // 创建任务  
  46.                 Job job = new Job(conf, WordCountTest.class.getName());  
  47.   
  48.                 // 天龙八部1.1  设置输入目录和设置输入数据格式化的类  
  49.                 FileInputFormat.setInputPaths(job, INPUT_PATH);  
  50.                 job.setInputFormatClass(NLineInputFormat.class);  
  51.   
  52.                 // 天龙八部1.2  设置自定义Mapper类和设置map函数输出数据的key和value的类型  
  53.                 job.setMapperClass(MyNLineInputFormatMapper.class);  
  54.                 job.setMapOutputKeyClass(Text.class);  
  55.                 job.setMapOutputValueClass(LongWritable.class);  
  56.   
  57.                 // 天龙八部1.3  设置分区和reduce数量(reduce的数量,和分区的数量对应,因为分区为一个,所以reduce的数量也是一个)  
  58.                 job.setPartitionerClass(HashPartitioner.class);  
  59.                 job.setNumReduceTasks(1);  
  60.   
  61.                 // 天龙八部1.4  排序、分组  
  62.                 // 天龙八部1.5  归约  
  63.                 // 天龙八部2.1  Shuffle把数据从Map端拷贝到Reduce端。  
  64.                 // 天龙八部2.2  指定Reducer类和输出key和value的类型  
  65.                 job.setReducerClass(MyNLineInputFormatReducer.class);  
  66.                 job.setOutputKeyClass(Text.class);  
  67.                 job.setOutputValueClass(LongWritable.class);  
  68.   
  69.                 // 天龙八部2.3  指定输出的路径和设置输出的格式化类  
  70.                 FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));  
  71.                 job.setOutputFormatClass(TextOutputFormat.class);  
  72.   
  73.   
  74.                 // 提交作业 退出  
  75.                 System.exit(job.waitForCompletion(true) ? 0 : 1);  
  76.               
  77.             } catch (Exception e) {  
  78.                 e.printStackTrace();  
  79.             }  
  80.         }  
  81.           
  82.     public static class MyNLineInputFormatMapper extends Mapper<LongWritable, Text, Text, LongWritable> {  
  83.   
  84.         // 定义一个LongWritable对象作为map输出的value类型  
  85.         LongWritable oneTime = new LongWritable(1);  
  86.         // 定义一个Text对象作为map输出的key类型  
  87.         Text word = new Text();  
  88.   
  89.         protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws IOException,  
  90.                 InterruptedException {  
  91.   
  92.             // 对每一行记录采用制表符(\t)进行分割  
  93.             String[] splits = value.toString().split("\t");  
  94.   
  95.             // 遍历字符串数组输出每一个单词  
  96.             for (String str : splits) {  
  97.   
  98.                 // 设置word  
  99.                 word.set(str);  
  100.                 // 把结果写出去  
  101.                 context.write(word, oneTime);  
  102.             }  
  103.         }  
  104.     }  
  105.   
  106.     public static class MyNLineInputFormatReducer extends Reducer<Text, LongWritable, Text, LongWritable> {  
  107.   
  108.         // 定义LongWritable对象最为Reduce输出的value类型  
  109.         LongWritable result = new LongWritable();  
  110.   
  111.         protected void reduce(Text key, Iterable<LongWritable> values, Reducer<Text, LongWritable, Text, LongWritable>.Context context) throws IOException,  
  112.                 InterruptedException {  
  113.   
  114.             int sum = 0;  
  115.   
  116.             // 遍历集合,计算每个单词出现的和  
  117.             for (LongWritable s : values) {  
  118.   
  119.                 sum += s.get();  
  120.             }  
  121.             // 设置result  
  122.             result.set(sum);  
  123.             // 把结果写出去  
  124.             context.write(key, result);  
  125.         }  
  126.     }  
  127. }  

你可能感兴趣的:(Hadoop中的NLineInputFormat)