【转载】Mapreduce实现自定义的InputFormat
转自:http://www.cnblogs.com/dlutxm/archive/2011/09/30/2196653.html
在mapreduce程序运行的开始阶段,hadoop需要将待处理的输入文件进行分割,按预定义的格式对文件读取等操作,这些操作都在InputFormat中进行。主要工作有以下3个:
1. Validate the input-specification of the job.
2. Split-up the input file(s) into logical InputSplits, each of which is then assigned to an individual Mapper.
3. Provide the RecordReader implementation to be used to glean input records from the logicalInputSplit for processing by the Mapper.
InputFormat是一个抽象类,他含有getSplits()和createRecordReader()抽象方法,在子类中必须被实现。这两个就是InputFormat的基本方法。getSplits()确定输入对象的切分原则,而createRecordReader()则可以按一定格式读取相应数据。通常默认情况下,不是直接实现InputFormat类,而是直接继承FileInputFormat类,这个类提供了很多对文件操作的方法,其中比较常用的就是isSpiitable()方法,该方法决定该文件是否进行分片操作。另外还有就是createRecordReader方法,该方法是为文件的分片定制一个recordreader,可以根据自己的需求来进行定制,只需要重写该函数。
下面我就以http://developer.yahoo.com/hadoop/tutorial/module5.html#types中的例子来实现自己的MyInputFormat,根据自己的需求定制自己的InputFormat。
比如数据格式如下:
ball 3.5,12.7,9.0
car 15,23.76,42.23
device 0.0,12.4,-67.1
下面我们以这样的一种形式读取数据,分割每一行数据,前面的比如ball作为key,后面的3个浮点数读入到Point3D对象中,那么该如何实现呢?以下是我在学习过程中的实现。
首先是对Point3D数据类型的定制,首先定制数据类型为了能够在网络中以流的形式进行传输,必须实现Writable接口,同时在mapreduce编程的过程中,需要根据key来对数据进行排序与分区,所以必须实现Comparable接口,因此就实现了一个更加高级的接口WritableComprable,同时可以满足上面两个要求。

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; import org.apache.hadoop.io.WritableComparable; public class Point3D implements WritableComparable{
public float x;
public float y;
public float z;
public Point3D(float x, float y, float z) {
super();
this.x = x;
this.y = y;
this.z = z;
}
public Point3D(){
this(0.0f,0.0f,0.0f);
}
public void set(float x,float y,float z){
this.x=x;
this.y=y;
this.z=z;
}
@Override
public void readFields(DataInput in) throws IOException {
// TODO Auto-generated method stub
x=in.readFloat();
y=in.readFloat();
z=in.readFloat(); }
@Override
public void write(DataOutput out) throws IOException {
// TODO Auto-generated method stub
out.writeFloat(x);
out.writeFloat(y);
out.writeFloat(z); }
public float distanceFromOrigin(){
return (float)Math.sqrt(x*x+y*y+z*z); }
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if(!(obj instanceof Point3D))
return false;
Point3D other=(Point3D)obj;
return this.x==other.x&&this.y==other.y&&this.z==other.z; }
@Override
public int hashCode() {
// TODO Auto-generated method stub
return Float.floatToIntBits(x)
^ Float.floatToIntBits(y)
^ Float.floatToIntBits(z);
}
@Override
public String toString() {
// TODO Auto-generated method stub
return Float.toString(x)+","+Float.toString(y)+","+Float.toString(z);
}
@Override
public int compareTo(Object ot) {
// TODO Auto-generated method stub
Point3D other=(Point3D)ot;
float myDistance=this.distanceFromOrigin();
float otherDistance=other.distanceFromOrigin();
return Float.compare(myDistance, otherDistance); } }

其次就是定制自己的Fortmat了

import java.io.IOException; import java.util.StringTokenizer; 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.JobContext;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.util.LineReader; public class MyInputFormat extends FileInputFormat<Text, Point3D> { @Override
protected boolean isSplitable(JobContext context, Path filename) {
// TODO Auto-generated method stub
return false;
}
@Override
public RecordReader<Text, Point3D> createRecordReader(InputSplit inputsplit,
TaskAttemptContext context) throws IOException, InterruptedException {
// TODO Auto-generated method stub
return new objPosRecordReader();
}
public static class objPosRecordReader extends RecordReader<Text,Point3D>{ public LineReader in;
public Text lineKey;
public Point3D lineValue;
public StringTokenizer token=null; public Text line; @Override
public void close() throws IOException {
// TODO Auto-generated method stub } @Override
public Text getCurrentKey() throws IOException, InterruptedException {
// TODO Auto-generated method stub
System.out.println("key");
//lineKey.set(token.nextToken());
System.out.println("hello");
return lineKey;
} @Override
public Point3D getCurrentValue() throws IOException,
InterruptedException {
// TODO Auto-generated method stub return lineValue;
} @Override
public float getProgress() throws IOException, InterruptedException {
// TODO Auto-generated method stub
return 0;
} @Override
public void initialize(InputSplit input, TaskAttemptContext context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
FileSplit split=(FileSplit)input;
Configuration job=context.getConfiguration();
Path file=split.getPath();
FileSystem fs=file.getFileSystem(job); FSDataInputStream filein=fs.open(file);
in=new LineReader(filein,job); line=new Text();
lineKey=new Text();
lineValue=new Point3D(); } @Override
public boolean nextKeyValue() throws IOException, InterruptedException {
// TODO Auto-generated method stub
int linesize=in.readLine(line);
if(linesize==0)
return false; token=new StringTokenizer(line.toString());
String []temp=new String[2];
if(token.hasMoreElements()){
temp[0]=token.nextToken();
if(token.hasMoreElements()){
temp[1]=token.nextToken();
}
}
System.out.println(temp[0]);
System.out.println(temp[1]);
String []points=temp[1].split(",");
System.out.println(points[0]);
System.out.println(points[1]);
System.out.println(points[2]);
lineKey.set(temp[0]);
lineValue.set(Float.parseFloat(points[0]),Float.parseFloat(points[1]), Float.parseFloat(points[2]));
System.out.println("pp");
return true;
} } }

测试的时候写的map函数,没有reudce,必须要在后面设置job的时候设置reduce的个数为0,job.setNumReduceTasks(0)。

import java.io.IOException; import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; public class TestMapper extends Mapper<Text, Point3D, Text, Point3D> { @Override
protected void map(Text key, Point3D value,
org.apache.hadoop.mapreduce.Mapper.Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
context.write(key, value);
} }
import java.io.IOException;
import java.net.URI; import javax.xml.soap.Text; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class TestMyInputFormat { /**
* @param args
* @throws IOException
* @throws ClassNotFoundException
* @throws InterruptedException
*/
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
// TODO Auto-generated method stub
System.out.println("nihao");
Job job=new Job();
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create(args[1]), conf);
fs.delete(new Path(args[1]));
job.setJobName("测试MyInputFormat程序。。。。。");
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.setInputFormatClass(MyInputFormat.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Point3D.class);
job.setMapperClass(TestMapper.class);
job.setNumReduceTasks(0);
job.waitForCompletion(false); } }

【转载】Mapreduce实现自定义的InputFormat的更多相关文章
- Spark设置自定义的InputFormat读取HDFS文件
本文通过MetaWeblog自动发布,原文及更新链接:https://extendswind.top/posts/technical/problem_spark_reading_hdfs_serial ...
- 自定义实现InputFormat、OutputFormat、输出到多个文件目录中去、hadoop1.x api写单词计数的例子、运行时接收命令行参数,代码例子
一:自定义实现InputFormat *数据源来自于内存 *1.InputFormat是用于处理各种数据源的,下面是实现InputFormat,数据源是来自于内存. *1.1 在程序的job.setI ...
- MapReduce之自定义InputFormat
在企业开发中,Hadoop框架自带的InputFormat类型不能满足所有应用场景,需要自定义InputFormat来解决实际问题. 自定义InputFormat步骤如下: (1)自定义一个类继承Fi ...
- 关于MapReduce中自定义分区类(四)
MapTask类 在MapTask类中找到run函数 if(useNewApi){ runNewMapper(job, splitMetaInfo, umbilical, reporter ...
- [转载] MapReduce工作原理讲解
转载自http://www.aboutyun.com/thread-6723-1-1.html 有时候我们在用,但是却不知道为什么.就像苹果砸到我们头上,这或许已经是很自然的事情了,但是牛顿却发现了地 ...
- Hadoop(16)-MapReduce框架原理-自定义FileInputFormat
1. 需求 将多个小文件合并成一个SequenceFile文件(SequenceFile文件是Hadoop用来存储二进制形式的key-value对的文件格式),SequenceFile里面存储着多个文 ...
- 关于MapReduce中自定义分组类(三)
Job类 /** * Define the comparator that controls which keys are grouped together * for a single ...
- 关于MapReduce中自定义带比较key类、比较器类(二)——初学者从源码查看其原理
Job类 /** * Define the comparator that controls * how the keys are sorted before they * are pa ...
- 关于MapReduce中自定义Combine类(一)
MRJobConfig public static fina COMBINE_CLASS_ATTR 属性COMBINE_CLASS_ATTR = "mapreduce.j ...
随机推荐
- IntelliJ IDEA 2019年最新版2019.3.1 安装激活教程【最强,可用至2100、2089年】
IntelliJ IDEA 2019年最新版 永久激活教程 本文包括最新[2019.3.1 & 1.3]激活 和[2018.3.2]激活 说明:①2019.3.②2019.1.③2018.3版 ...
- [转]三分钟学会.NET Core Jwt 策略授权认证
[转]三分钟学会.NET Core Jwt 策略授权认证 一.前言# 大家好我又回来了,前几天讲过一个关于Jwt的身份验证最简单的案例,但是功能还是不够强大,不适用于真正的项目,是的,在真正面对复杂而 ...
- jQuery---内容复习
内容复习 1. 操作样式 (5) 1.1 css操作 设置单个样式 设置多个样式 获取样式 css(name, value) :设置单个样式 css(obj):设置多个样式 css(name):获取样 ...
- jQuery---淘宝精品案例
淘宝精品案例 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UT ...
- ASP.NET MVC5 的请求管道和运行生命周期
https://www.jianshu.com/p/848fda7f79e0 请求处理管道 请求管道是一些用于处理HTTP请求的模块组合,在ASP.NET中,请求管道有两个核心组件:IHttpModu ...
- 牛客练习赛53 C题bitset
题目链接https://ac.nowcoder.com/acm/contest/1114/C #include<bits/stdc++.h> using namespace std; #d ...
- weblogic的ssrf漏洞
前言 什么是ssrf SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞. 一般情况下,SSRF攻击的目标 ...
- Android_侧滑菜单的实现
1.创建侧滑菜单Fragment package com.example.didida_corder; import android.os.Bundle; import android.view.La ...
- [TJOI2009] 猜数字 - 中国剩余定理
现有两组数字,每组k个,第一组中的数字分别为:a1,a2,...,ak表示,第二组中的数字分别用b1,b2,...,bk表示.其中第二组中的数字是两两互素的.求最小的非负整数n,满足对于任意的i,n ...
- 避免layui form表单重复触发submit绑定事件
个人博客 地址:http://www.wenhaofan.com/article/20180927002336 在使用以下代码监听lay-filter为editConfig的提交按钮后,当点击提交按钮 ...