(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)以怎样的方式从分片中读取一条记录,每读取一条记录都会调用RecordReader类: (2)系统默认的RecordReader是LineRecordReader,如TextInputFormat ...
- Vue.js学习 Item11 – 组件与组件间的通信
什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有 ...
- Vue中父子组件通讯——组件todolist
一.todolist功能开发 <div id="root"> <div> <input type="text" v-model=& ...
- $Django Rest Framework-认证组件,权限组件 知识点回顾choices,on_delete
一 小知识点回顾 #orm class UserInfo (models.Model): id = models.AutoField (primary_key=True) name = models. ...
- Vuejs——(12)组件——动态组件
版权声明:出处http://blog.csdn.net/qq20004604 目录(?)[+] 本篇资料来于官方文档: http://cn.vuejs.org/guide/components ...
- python 全栈开发,Day78(Django组件-forms组件)
一.Django组件-forms组件 forms组件 django中的Form组件有以下几个功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显 ...
- slot是标签的内容扩展,也就是说你用slot就可以在自定义组件时传递给组件内容,组件接收内容并输出
html 父页面<div id="app"> <register> <span slot="name">{{message. ...
- 040——VUE中组件之组件间的数据参props的使用实例操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue02—— 动画、组件、组件之间的数据通信
一.vue中使用动画 文档:https://cn.vuejs.org/v2/guide/transitions.html 1. Vue 中的过渡动画 <!DOCTYPE html> < ...
随机推荐
- 面向对象---prototype
构造函数里的this,外面的new <script> //用工厂方式构造对象 function createPerson(name, sex) //构造函数 { //假想的系统内部工作流程 ...
- 关于ListView嵌套GridView中的onItemClickListener失效问题
一开始在ListView中设置了onItemClickListener,在里面Log输出Item列表的位置,完全没有反应, 网上大部分说的什么把子组件屏蔽掉(而且好多都是转载的一样的), 可是我希望的 ...
- bootstrap-datepicker 日期格式设置
[参考文档]http://bootstrap-datepicker.readthedocs.org/en/latest/ datepicker插件默认是时间格式为mm/dd/yyyy,如何更改时间的格 ...
- Scrum Meeting---Four(2015-10-28)
今日已完成任务和明日要做的任务 姓名 今日已完成任务 今日时间 明日计划完成任务 估计用时 董元财 今日我完成了数据库表的设计以及创建 3h 进行Java Web工程的编写 4h 胡亚坤 用户之间的通 ...
- javascript获取类元素
代码测试是ie5+: 原生javascript中筛选出含有指定类的元素: 思想:在指定范围里把所有的元素筛选出来,然后把里面的每个元素都遍历找出它们含有的所有类,然后逐个元素遍历它们各自的类,如果指定 ...
- iOS - MVP 架构模式
1.MVP 从字面意思来理解,MVP 即 Modal View Presenter(模型 视图 协调器),MVP 实现了 Cocoa 的 MVC 的愿景.MVP 的协调器 Presenter 并没有对 ...
- Class.asSubclass浅谈
这是java.lang.Class中的一个方法,作用是将调用这个方法的class对象转换成由clazz参数所表示的class对象的某个子类.举例来说, 上面的代码将strList.getClass() ...
- [转载] C++11中的右值引用
C++11中的右值引用 May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移动语义std::move() 右值引用和右值的关系 完美转发 引用折叠推导 ...
- jQuery插件开发全解析
jQuery插件的开发包括两种: 一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法.jQuery的全局函数就是属于jQuery命名空间的函数,另一种是对象级 ...
- 转:C++中Static作用和使用方法
转自:http://blog.csdn.net/artechtor/article/details/2312766 1.什么是static? static 是C++中很常用的修饰符,它被用 ...