Mapreduce的输入格式

map(k1,v1)——>list(k2,v2)
reduce(k2,list(v2))->list(k3,v3)
reduce的输入类型必须与map函数的输出类型相同
combine的输入输出键值类型必须相同,也就是k2,v2

static class Mapper extends Mapper<Object,Text,Text,Text>
{
public void map(Object key, Text value, Context context)throws IOException,Interrupution
{
}
}

static class Reducer extends Reudcer<Text,Text,Text,Text>
{
public void reduce(Text key,Iterable<Text> values, Context context) throws IOException,Interrupution
{

}

}

partion 函数将中间的键值对进行处理,并且返回一个分区索引。实际上分区由键单独决定,值是被忽略的。

public class HashPation<k2,v2> implments Partioner<k2,v2>{

public void configure(JobConf job) {}
public int getPartion(K2 key, V2 value, int numPartions){
return(key.hashCode() & Interger.MAX_VALUE &numPartions);

}
}

mr的二次排序



一个输入分片就是由单个map处理的输入块。每一个map操作只处理一个输入分片。每个分片被划分为若干记录,每条记录就是一个键值对。

public interface InputSplit extends Writable{

long getLength() throws IOException; 字节为单位的长度,长度用来排序分片,以便有限处理最大的分片

String[] getLocation() throws IOException; 存储位置(即一组机器名)
}

MapReduce应用开发人员不需要直接处理InputSplit,因为它是由InputFormat创建的,InputFormat负责产生输入分片并将他们分割成记录。
public interface   InputFormat <K,V>
{
InputSpli t [] getSplits(JobConf job, int numSplits) throws IOExcetion;
RecordReader<K,V> getRecordReader(InputSplit split, JobConf job, Reporter reporter)throws IOExcepition;
}

map任务用 RecordReader来生成记录的键值对( 下面这几个函数都是比较重要的要记住

K key=reader.createKey();
V value = reader.createValue();
while(reader.next(key,value))
{
mapper.map( key,value,context);
}

RecordReader的next方法被反复的调用以便为mapper生成键值对。

FileInputFormat类

控制分片大小的属性
mapred.min.split.size  文件分片最小有效字节数
mapred.max.split.size  最大有效字节数
dfs.blokc.size HDFS中块的大小 

CombineFileInputFormat
FileInputFormat 为每个文件产生一个分片,而CombineFileInputFormat把多个文件打包到一个分片中一边每个mapper可以处理更多的数据。关键是
决定哪些分片放入同一个分片时,CombineInputFormat会考虑到节点和机架的因素,所以,在典型MapReduce作业处理输入的速度不会下降。

FileSystem fs = FileSystem.get(URI.create(uri),conf);
Path[] paths = new Path[args.lengths];
for(int i = 0;i<pahts.length;i++)
{
paths[i]=new Path(args[i]);
}
FileStatus[] status = fs.listStatus(pahts);
Path[] listedPaths= FileUtil.stat2Paths(status);
for(Path p : listedPaths){
System.out.println(p);
}


if (file.isFile()) {
System.out.print("文件 :" + file.getName() + "\t");
}// 是目录的情况
else {
File[] files = file.listFiles();
for (File fileTemp : files) {
if (fileTemp.isDirectory()) {
System.out.println(temp + "目录 :" + fileTemp.getName()
+ "\t");

一个可以解决大量小文件的方法是使用SequenceFile将这些小文件合并成一个或多个大文件:可以将文件名作为键,文件内容做为值。
CombineFileInputFormat是一个抽象类,没有提供实体类。所以使用的时候需要一些额外的工作。需要创建一个CombineFileInputFormat的具体子类,并且实现getRecordReader()方法。

避免切分的方法有两种,一种是扩大分片的大小。第二种就是使用FileInputFormat的具体子类,并且重载isSplitable()方法,把返回值设置为false。例如下面的例子
public NonSplitableTextInputformat extends TextInputformat{
poretected boolean   isSplitable(FileSystem fs , Path file)
{
return false;
}
}

文件输入分片的属性
map.input.file   输入文件的路径 String filename  =   conf.get("map.input.file"); 获得输入文件的名字

map.input.start  分片开始处的字节便宜量

map.input.length    分片的长度

文本输入 TextInputFormat

TextInputformat是默认的InputFormat,每条记录是一行输入,键是LongWritable类型,是该行在文件中的字节偏移量( 很难取得行号,因为文件是按字节而不是按行切分为分片)。值是这行的内容。

KeyValueTextInputFormat  对于一行就包含了key和value的情况很实用。
可以通过 key.value.separator.in.input.line属性来指定分隔符。选定命令用如下对命令来设置。

NlineInputFormat
通过 mapred.line.input.format.linespermap  属性来设置N的值

Hadoop提供了StreamXmlRecordReader类,在org.apache.haodoop.streaming包中,通过把输入格式设置成StreamInputFormat,把stream.recordreader.class属性设置为org.apache.Haodoop.Streaming.StreamXmlRecorderReader来使用StreamXmlRecordReader类。


二进制输入
SequenceFileInputFormat  

对于多种输入
对于多种输入  使用MultipleInputs.addInputPath(conf, ncdcInputPaht,TextInputFormat.class,   MaxTemPeratureMapper.class)
                           MultipleInputs.addInputPath(conf, metofficeInputPath,TextInputFormat.class, MetofficeMaxTemPeratureMapper.class)

数据库输入使用的是DBInputFormat 专业工具是Sqoop

  Partitioner是partitioner的基类,如果需要定制partitioner也需要继承该类。         
该类有一个比较重要的函数就是int getPartion(K key,V value,int numPartions)         返回要分的个数 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值