(1)以怎样的方式从分片中读取一条记录,每读取一条记录都会调用RecordReader类;

(2)系统默认的RecordReader是LineRecordReader,如TextInputFormat;而SequenceFileInputFormat的RecordReader是SequenceFileRecordReader;
(3)LineRecordReader是用每行的偏移量作为map的key,每行的内容作为map的value;
(4)应用场景:自定义读取每一条记录的方式;自定义读入key的类型,如希望读取的key是文件的路径或名字而不是该行在文件中的偏移量。
 
自定义RecordReader:
(1)继承抽象类RecordReader,实现RecordReader的一个实例;
(2)实现自定义InputFormat类,重写InputFormat中createRecordReader()方法,返回值是自定义的RecordReader实例;
(3)配置job.setInputFormatClass()设置自定义的InputFormat实例;
 
源码见org.apache.mapreduce.lib.input.TextInputFormat类;
 
RecordReader例子:
应用场景:
数据:
1
2
3
4
5
6
7
......
要求:分别计算奇数行与偶数行数据之和
奇数行综合:10+30+50+70=160
偶数行综合:20+40+60=120
 
新建项目TestRecordReader,包com.recordreader,
源代码MyMapper.java:
package com.recordreader;
 
import java.io.IOException;
 
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
 
public class MyMapper extends Mapper {
 
@Override
protected void map(LongWritable key, Text value,Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
context.write(key, value);
}
 
}
 
 
源代码MyPartitioner.java:
package com.recordreader;
 
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;
 
public class MyPartitioner extends Partitioner {
 
@Override
public int getPartition(LongWritable key, Text value, int numPartitions) {
// TODO Auto-generated method stub
if(key.get() % 2 == 0){
key.set(1);
return 1;
}
else {
key.set(0);
return 0;
}
}
 
}
 
源代码MyReducer.java:
package com.recordreader;
 
import java.io.IOException;
 
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
 
public class MyReducer extends Reducer {
 
@Override
protected void reduce(LongWritable key, Iterable value,Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
int sum = 0;
for(Text val: value){
sum += Integer.parseInt(val.toString());
}
Text write_key = new Text();
IntWritable write_value = new IntWritable();
if(key.get() == 0)
write_key.set("odd:");
else 
write_key.set("even:");
write_value.set(sum);
context.write(write_key, write_value);
}
 
}
 
源代码MyRecordReader.java:
package com.recordreader;
 
import java.io.IOException;
 
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.util.LineReader;
 
public class MyRecordReader extends RecordReader {
private long start;
private long end;
private long pos;
private FSDataInputStream fin = null;
private LongWritable key = null;
private Text value = null;
private LineReader reader = null;
@Override
public void close() throws IOException {
// TODO Auto-generated method stub
fin.close();
}
 
@Override
public LongWritable getCurrentKey() throws IOException,
InterruptedException {
// TODO Auto-generated method stub
return key;
}
 
@Override
public Text getCurrentValue() throws IOException, InterruptedException {
// TODO Auto-generated method stub
return value;
}
 
@Override
public float getProgress() throws IOException, InterruptedException {
// TODO Auto-generated method stub
return 0;
}
 
@Override
public void initialize(InputSplit inputSplit, TaskAttemptContext context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
FileSplit fileSplit = (FileSplit)inputSplit;
start = fileSplit.getStart();
end = start + fileSplit.getLength();
Configuration conf = context.getConfiguration();
Path path = fileSplit.getPath();
FileSystem fs = path.getFileSystem(conf);
fin = fs.open(path);
fin.seek(start);
reader = new LineReader(fin);
pos = 1;
}
 
@Override
public boolean nextKeyValue() throws IOException, InterruptedException {
// TODO Auto-generated method stub
if(key == null)
key = new LongWritable();
key.set(pos);
if(value == null)
value = new Text();
if(reader.readLine(value) == 0)
return false;
pos++;
return true;
}
 
}
 
源代码MyFileInputFormat.java:
package com.recordreader;
 
import java.io.IOException;
 
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.JobContext;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
 
public class MyFileInputFormat extends FileInputFormat {
 
@Override
public RecordReader createRecordReader(InputSplit arg0,
TaskAttemptContext arg1) throws IOException, InterruptedException {
// TODO Auto-generated method stub
return new MyRecordReader();
}
 
@Override
protected boolean isSplitable(JobContext context, Path filename) {
// TODO Auto-generated method stub
return false;
}
 
}
 
源代码TestRecordReader.java:
package com.recordreader;
 
import java.io.IOException;
 
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
 
 
 
public class TestRecordReader {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException{
  Configuration conf = new Configuration();
   String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
   if (otherArgs.length != 2) {
     System.err.println("Usage: wordcount ");
     System.exit(2);
   }
   Job job = new Job(conf, "word count");
   job.setJarByClass(TestRecordReader.class);
   job.setMapperClass(MyMapper.class);
   
   job.setReducerClass(MyReducer.class);
   job.setPartitionerClass(MyPartitioner.class);
   job.setNumReduceTasks(2);
   job.setInputFormatClass(MyFileInputFormat.class);
   
   
   
   FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
   FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
   System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}

MapReduce 重要组件——Recordreader组件 [转]的更多相关文章

  1. MapReduce 重要组件——Recordreader组件

    (1)以怎样的方式从分片中读取一条记录,每读取一条记录都会调用RecordReader类: (2)系统默认的RecordReader是LineRecordReader,如TextInputFormat ...

  2. Vue.js学习 Item11 – 组件与组件间的通信

    什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有 ...

  3. Vue中父子组件通讯——组件todolist

    一.todolist功能开发 <div id="root"> <div> <input type="text" v-model=& ...

  4. $Django Rest Framework-认证组件,权限组件 知识点回顾choices,on_delete

    一 小知识点回顾 #orm class UserInfo (models.Model): id = models.AutoField (primary_key=True) name = models. ...

  5. Vuejs——(12)组件——动态组件

    版权声明:出处http://blog.csdn.net/qq20004604   目录(?)[+]   本篇资料来于官方文档: http://cn.vuejs.org/guide/components ...

  6. python 全栈开发,Day78(Django组件-forms组件)

    一.Django组件-forms组件 forms组件 django中的Form组件有以下几个功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显 ...

  7. slot是标签的内容扩展,也就是说你用slot就可以在自定义组件时传递给组件内容,组件接收内容并输出

    html 父页面<div id="app"> <register> <span slot="name">{{message. ...

  8. 040——VUE中组件之组件间的数据参props的使用实例操作

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. vue02—— 动画、组件、组件之间的数据通信

    一.vue中使用动画 文档:https://cn.vuejs.org/v2/guide/transitions.html 1. Vue 中的过渡动画 <!DOCTYPE html> < ...

随机推荐

  1. 一个异常与Android Studio系列教程参考

    由于编译过程中遇到了错误:

  2. 杭电HDU1042(有点坑的高精度)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1042 题意: Given an integer N(0 ≤ N ≤ 10000), your task i ...

  3. mfc 可编辑 list control

    维护到一个古老的gm工具的时候 需要这个功能 在网上找到一份很好用的代码 贴到这里 再次感谢那位同僚 #pragma once //#include "OrangeMessage.h&quo ...

  4. 2013 Multi-University Training Contest 2

    HDU-4611 Balls Rearrangement 题意:具体题意不大清楚,最后要处理一个这样的表达式:sum{ |i % a - i % b| },0 <= i < N 的取值很大 ...

  5. bootstrap学习笔记<六>(表单二之按钮)

    按钮(补充) (ps:居中元素可以使用<center></center>标签) 块级按钮(ps:按钮占一整行) <button class="btn btn-p ...

  6. 【Todo】OSGi学习

    经常听到.见到OSGi这个名字.那么就单开一篇文章记录一下对OSGi的学习吧. 主要是做一些概念上面的学习.暂时不打算深入实践. 主要参考:http://www.osgi.com.cn/article ...

  7. C++—函数探幽

    一.内联函数 1.内联函数的机制 内联函数是C++为提高程序运行速度而做的一项改进. 函数调用机制:常规函数调用使程序使程序跳到被掉函数的地址,并在函数结束时返回. 内联函数的机制:内联函数的代码与其 ...

  8. 转:C/C++基本数据类型所占字节数

    参考:http://blog.csdn.net/vast_sea/article/details/8076934 关于这个基本的问题,很早以前就很清楚了,C标准中并没有具体给出规定那个基本类型应该是多 ...

  9. 【CITE】C#入门学习-----简单画图程序

    版权声明:本文为博主原创文章,未经博主允许不得转载. 欢迎大家提出意见,一起讨论! 转载请标明是引用于 http://blog.csdn.net/chenyujing1234 通过本实例了解如何在窗体 ...

  10. 扒一扒JavaScript 预解释

    带var关键字预解释 让我们先看下这段代码执行的结果: 代码如下: alert(n);//弹出undefinedvar n = 10; 弹出的结果是undefined,为何不是10?让我们再看下面这段 ...