MapReduce深入理解输入和输出格式(2)-输入和输出完全总结
MapReduce太高深,性能也值得考虑,大家感兴趣的还是看看spark比较好。
FileInputFormat类
FileInputFormat是所有使用文件为数据源的InputFormat实现的基类,它提供了两个功能:一个定义哪些文件包含在一个作业的输入中;一个为输入文件生成分片的实现,把分片割成记录的作业由其子类来完成。
下图为InputFormat类的层次结构
:
FileInputFormat 类输入路径
FileInputFormat 提供四种静态方法来设定 Job 的输入路径,其中下面的 addInputPath() 方法 addInputPaths() 方法可以将一个或多个路径加入路径列表,setInputPaths() 方法一次设定完整的路径列表(可以替换前面所设路径)
1
2
3
4
|
public static void addInputPath(Job
public static void addInputPaths(Job
public static void setInputPaths(Job
public static void setInputPaths(Job |
一个路径可以是一个文件一个目录或者是一个glob ,即一个文件和目录的集合目录路径包含这个目录下的所有文件对目录路径的处理并不是递归的。事实上,这些目录只能包含文件。如果包含文件 夹.那么它会被当作(普通)文件处理,从而产生错误。为此,可以使用一个文件 glob
或者一个过滤器来选择需要处理的文件。
如果需要排除特定文件,可以使用 FileInputFormat 的 setInputPathFilter() 设置一个过滤器: public
它默认过滤隐藏文件中以”_“和”.“开头的文件
static void setInputPathFilter(Job job, Class<? extends PathFilter> filter);
即使不手动设置过滤器, FilelnputFormat 也会自动设置一个默认的过滤器来排 除隐藏文件(即以.. ..和"_开头的文件)。如巢调用setlnputPathFilter (), 那么它会在原有默认过滤器的基础上增加一个过滤器。也就是说,自定义的过滤器只能看到非隐藏文件。
1
2
3
4
5
6
|
private static final PathFilter new PathFilter(){
public boolean accept(Path
String
return !name.startsWith( "_" ) "." ); }
}; |
FileInputFormat 类的输入分片
FilelnputFormat 是如何将文件转换为输入分片的呢? FilelnputF ormat 只会分 制大文件。这里的"大"指的是大于HDFS 块的大小,这在大多应用程序中是合理的,然而,这个值也可以通过设置不同的Hadoop
变量而改变。
FileInputFormat 类一般分割超过 HDFS 块大小的文件。通常分片与 HDFS 块大小一样,然后分片大小也可以改变的,下面展示了控制分片大小的属性:
1
2
3
|
FileInputFormat computeSplitSize( long goalSize, long minSize, long blockSize)
return Math.max(minSize,
} |
最大的分片大小默认是Java 中long 类型的最大值.当色的值被设置成小于块大小 时,那么将强制分片的大小小子块。 分片的大小是由下述的公式得到的(参见FilelnputFormat
的computeSplitSiz e () 方法):
minimumSize < blockSize < maximumSize 分片的大小即为块大小。
重载 FileInputFormat 的 isSplitable() =false 可以避免 mapreduce 输入文件被分割。
小文件与CombineFileInputFormat
CombineFileInputFormat 是针对小文件设计的,CombineFileInputFormat 会把多个文件打包到一个分片中,以便每个 mapper 可以处理更多的数据;减少大量小文件的另一种方法可以使用 SequenceFile 将这些小文件合并成一个或者多个大文件。
CombineFileInputFormat 不仅对于处理小文件实际上对于处理大文件也有好处,本质上,CombineFileInputFormat 使 map 操作中处理的数据量与 HDFS 中文件的块大小之间的耦合度降低了
CombineFileInputFormat 是一个抽象类,没有提供实体类,所以需要实现一个CombineFileInputFormat 具体 类和 getRecordReader() 方法(旧的接口是这个方法,新的接口InputFormat中则是createRecordReader())
避免分割
可以处理一整个文件。比如.检查文件中的记录是否有序的一个简单的方站是顺序扫描每一条记录并且比较前一条记录是否比后一条要小(或相等).如果要将它实现为一个map
操作,那么这个map 操作必须能够访问整个文件飞有很多方法可以保证输入文件不被分割。第一种(最简单但不怎么漂亮的)方在去就是增加最小分片大小,将它设置成大于要处理的最大文件大小,当然也可以将它设置成long.MAX_VALUE.
也就是输入分片大小的上限.另外一种方法就是继承FilelnputFormat 实体类,并且重载isSplitable() 方桂气将它的返回值设置为false.
把整个文件作为一条记录处理
有时,mapper 需要访问问一个文件中的全部内容。即使不分割文件,仍然需要一个 RecordReader 来读取文件内容为 record 的值,下面给出实现这个功能的完整程序,详细解释见《Hadoop权威指南》。
将若干个小文件打包成SequenceFi le 的MapReduce 任务
由于输入的格式是WholeFilelnputForma t ,所以mapper 只需要找到输入文件分片的文件名.它是通过访问JobConf 对象的map.input . file 属性, 而此属性被MapReduce 框架设置成输入分片的文件名,但只针对FileSp1it 的实例(包括大多数F i1elnputFormat 的子类). Reducer 的类型是IdentityReducer ,而输出格式是SequenceFi1eOutput Format.
文本处理
TextInputFileFormat 是默认的 InputFormat,每一行就是一个纪录
TextInputFileFormat 的 key 是 LongWritable 类型,存储该行在整个文件的偏移量,value 是每行的数据内容,不包括任何终止符(换行符和回车符),它是Text类型. 如下例 On the top of the Crumpetty Tree
The Quangle Wangle sat,
But his face you could not see,
On account of his Beaver Hat.
每条记录表示以下key/value对
(0, On the top of the Crumpetty Tree)
(33, The Quangle Wangle sat,)
(57, But his face you could not see,)
(89, On account of his Beaver Hat.输入分片与 HDFS 块之间的关系:TextInputFormat 每一条纪录就是一行,很可能某一行跨数据库存放。
KeyValueTextInputFormat。对下面的文本,KeyValueTextInputFormat 比较适合处理,其中可以通过 mapreduce.input.keyvaluelinerecordreader.key.value.separator 属性设置指定分隔符,默认 值为制表符,以下指定”→“为分隔符
line1→On the top of the Crumpetty Tree
line2→The Quangle Wangle sat,
line3→But his face you could not see,
line4→On account of his Beaver Hat.NLineInputFormat。如果希望 mapper 收到固定行数的输入,需要使用 NLineInputFormat 作为 InputFormat 。与 TextInputFormat 一样,key是文件中行的字节偏移量,值是行本身。
N 是每个 mapper 收到的输入行数,默认时 N=1,每个 mapper 会正好收到一行输入,mapreduce.input.lineinputformat.linespermap 属性控制 N 的值。以刚才的文本为例。 如果N=2,则每个输入分片包括两行。第一个 mapper 会收到前两行 key/value 对:
(0, On the top of the Crumpetty Tree)
(33, The Quangle Wangle sat,)
另一个mapper则收到:
(57, But his face you could not see,)
(89, On account of his Beaver Hat.)
二进制输入
SequenceFileInputFormat 如果要用顺序文件数据作为 MapReduce 的输入,应用 SequenceFileInputFormat。key 和 value 顺序文件,所以要保证map输入的类型匹配
SequenceFileInputFormat 可以读 MapFile 和 SequenceFile,如果在处理顺序文件时遇到目录,SequenceFileInputFormat 类会认为值正在读 MapFile 数据文件。
SequenceFileAsTextInputFormat 是 SequenceFileInputFormat 的变体。将顺序文件(其实就是SequenceFile)的 key 和 value 转成 Text 对象
SequenceFileAsBinaryInputFormat是 SequenceFileInputFormat 的变体。将顺序文件的key和value作为二进制对象
多种输入
对于不同格式,不同表示的文本文件输出的处理,可以用 MultipleInputs 类里处理,它允许为每条输入路径指定 InputFormat 和 Mapper。
MultipleInputs 类有一个重载版本的 addInputPath()方法:
- 旧api列举
1
public
static
void
addInputPath(JobConf
conf, Path path, Class<?extends
InputForma
t> inputFormatClass)
- 新api列举
1
public
static
void
a
ddInputPath(Job job, Path path, Class<?extends
InputFormat>
inputFormatClass)
在有多种输入格式只有一个mapper时候(调用Job的setMapperClass()方法),这个方法会很有用。
DBInputFormat
JDBC从关系数据库中读取数据的输入格式(参见权威指南)
总结:
输入格式 |
描述 |
键 |
值 |
TextInputFormat |
默认格式,读取文件的行 |
行的字节偏移量 |
行的内容 |
KeyValueInputFormat |
把行解析为键值对 |
第一个tab字符前的所有字符 |
行剩下的内容 |
SequenceFileInputFormat |
Hadoop定义的高性能二进制格式 |
用户自定义 |
用户自定义 |
SequenceFileAsTextInputFormat | 是SequenceFileInputFormat的变体,它将键和值转换为Text对象。转换的时候会调用键和值的toString方法。这个格式可以是顺序文件作为流操作的输入。 | ||
SequenceFileAsBinaryInputFormat | SequenceFileAsBinaryInputFormat是SequenceFileInputFormat的另一种变体,它将顺序文件的键和值作为二进制对象,它们被封装为BytesWritable对象,因而应用程序可以任意地将这些字节数组解释为他们想要的类型。 | ||
DBInputForma | DBInputForma是一个使用JDBC并且从关系数据库中读取数据的一种输入格式。由于它没有任何碎片技术,所以在访问数据库的时候必须非常小心,太多的mapper可能会事数据库受不了。因此DBInputFormat最好在加载小量数据集的时候用。 |
输出格式
OutputFormat类的层次结构
文本输出
默认输出格式是 TextOutputFormat,它本每条记录写成文本行,key/value 任意,这里 key和value 可以用制表符分割,用 mapreduce.output.textoutputformat.separator 书信可以改变制表符,与TextOutputFormat 对应的输入格式是
KeyValueTextInputFormat。
可以使用 NullWritable 来省略输出的 key 和 value。
二进制输出
- SequenceFileOutputFormat 将它的输出写为一个顺序文件,因为它的格式紧凑,很容易被压缩,所以易于作为 MapReduce 的输入
- 把key/value对作为二进制格式写到一个 SequenceFile 容器中
- MapFileOutputFormat 把 MapFile 作为输出,MapFile 中的 key 必需顺序添加,所以必须确保 reducer 输出的 key 已经排好序。
多个输出
MultipleOutputFormat 类可以将数据写到多个文件中,这些文件名称源于输出的键和值。MultipleOutputFormat是个抽象类,它有两个子类:MultipleTextOutputFormat 和 MultipleSequenceFileOutputFormat 。它们是
TextOutputFormat 的和 SequenceOutputFormat 的多版本。MultipleOutputs 类 用于生成多个输出的库,可以为不同的输出产生不同的类型,无法控制输出的命名。它用于在原有输出基础上附加输出。输出是制定名称的。
MultipleOutputFormat和MultipleOutputs的区别
这两个类库的功能几乎相同。MultipleOutputs 功能更齐全,但 MultipleOutputFormat 对 目录结构和文件命令更多de控制。
特征 | MultipleOutputFormat | MultipleOutputs |
完全控制文件名和目录名 | 是 | 否 |
不同输出有不同的键和值类型 | 否 | 是 |
从同一作业的map和reduce使用 | 否 | 是 |
每个纪录多个输出 | 否 | 是 |
与任意OutputFormat一起使用 | 否,需要子类 | 是 |
延时输出
有些文件应用倾向于不创建空文件,此时就可以利用 LazyOutputFormat (Hadoop 0.21.0版本之后开始提供),它是一个封装输出格式,可以保证指定分区第一条记录输出时才真正的创建文件,要使用它,用JobConf和相关输出格式作为参数来调用 setOutputFormatClass() 方法.
Streaming 和 Pigs 支持 -LazyOutput 选项来启用 LazyOutputFormat功能。
数据库输出
关系数据和 HBase的输出格式。
总结:
下表给出了已提供的输出格式:
输出格式 |
描述 |
TextOutputFormat |
默认的输出格式, 以 "key \t value" 的方式输出行 |
SequenceFileOutputFormat |
输出二进制文件,适合于读取为子MapReduce作业的输入 |
NullOutputFormat |
忽略收到的数据,即不做输出 |
SequenceFileAsBinaryOutputFormat | 与SequenceFileAsBinaryInputFormat相对应,它将键/值对当作二进制数据写入一个顺序文件 |
MapFileOutputFormat | MapFileOutputFormat将结果写入一个MapFile中。MapFile中的键必须是排序的,所以在reducer中必须保证输出的键有序。 |
MapReduce深入理解输入和输出格式(2)-输入和输出完全总结的更多相关文章
- c语言第一次作业——输入与输出格式
一.PTA实验作业 1.温度转换 本题要求编写程序,计算华氏温度150°F对应的摄氏温度.计算公式:C=5×(F−32)/9,式中:C表示摄氏温度,F表示华氏温度,输出数据要求为整型. 1.实验代码 ...
- SAS 输入与输出格式
SAS 输入与输出格式 一.认识SAS中的数据格式 SAS 中的格式有: 数字型 字符型 日期型 1.其中数字型的格式有一下集中表示方式: 整型数值:321 浮点数值:321.123 带逗号的数值:1 ...
- Hadoop 对MapReduce的理解
对MapReduce的理解 客户端启动一个作业 向JobTraker请求一个JobId 将资源文件复制到HDFS上,包括Jar文件,配置文件,输入划分信息等 接收作业后,进入作业队列,根据输入划分信息 ...
- 编程计算2×3阶矩阵A和3×2阶矩阵B之积C。 矩阵相乘的基本方法是: 矩阵A的第i行的所有元素同矩阵B第j列的元素对应相乘, 并把相乘的结果相加,最终得到的值就是矩阵C的第i行第j列的值。 要求: (1)从键盘分别输入矩阵A和B, 输出乘积矩阵C (2) **输入提示信息为: 输入矩阵A之前提示:"Input 2*3 matrix a:\n" 输入矩阵B之前提示
编程计算2×3阶矩阵A和3×2阶矩阵B之积C. 矩阵相乘的基本方法是: 矩阵A的第i行的所有元素同矩阵B第j列的元素对应相乘, 并把相乘的结果相加,最终得到的值就是矩阵C的第i行第j列的值. 要求: ...
- c#部分---用结构体的题目- //请输入班级人数,输入每个人的学号,姓名,和语文分数、数学分数和英语分数(要求使用结构体)
//请输入班级人数,输入每个人的学号,姓名,和语文分数.数学分数和英语分数(要求使用结构体), //求班级里两个语文分数是最高分的学生的所有信息:数学分数是最高分的两个学生的所有信息:英语平均分 建立 ...
- (19)IO流之字符流FileReader和FileWriter,缓冲字符流---缓冲输入字符流BufferedReader和缓冲输出字符流BufferedWriter
字符流,读取的文件是字符的时候,有两个基类一个是Reader,一个是Writer这有点拟人的感觉,人直接看懂的是文字 字符流 字节流:读取的是文件中的二进制字节流并不会帮你转换成看的懂得字符 字符流: ...
- Python实现使用tkinter弹出输入框输入数字, 具有确定输入和清除功能
Python3.6中用tkinter, 弹出可以输入数字的输入框. # Copyright (c) 2017-7-21 ZhengPeng All rights reserved. def pop_u ...
- html input验证只能输入数字,不能输入其他
html input验证只能输入数字,不能输入其他 此方法为借鉴别人的,在此只做记录. <input type="text" onkeyup="if(!/^\d+$ ...
- elementUi中input输入字符光标在输入一个字符后,光标失去焦点
elementUi中input输入字符光标在输入一个字符后,光标就退出,无法输入需要再次聚焦然后输入一个字符又再次退出 首先,用elementUi正常用v-model绑定输入的值是不会造成光标退出的, ...
随机推荐
- hysbz3676 回文串 回文自动机
回文自动机模板题 头铁了一下午hdu6599,最后发现自己的板有问题 先放这里一个正确性得到基本确认的板,过两天肝hdu6599 #pragma GCC optimize(2) #include< ...
- ECMAScript 2016,2017 和 2018 中所有新功能的示例
很难追踪 JavaScript(ECMAScript)中的新功能. 想找到有用的代码示例更加困难. 因此,在本文中,我将介绍 TC39 已完成 ES2016,ES2017 和 ES2018(最终草案) ...
- Linux课程---13、linux中任务计划介绍(任务计划分类)
Linux课程---13.linux中任务计划介绍(任务计划分类) 一.总结 一句话总结: 1.一次性任务计划:at 2.周期性任务计划:crontab 1.linux中如何添加一次性任务计划? at ...
- JAVA 设计模式之 原型模式详解
原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式利用的是克隆的原理,创建新的对象,JDK提供的Cloneable 和JSON. ...
- PostMan授权认证使用
Authorization 对于很多应用,出于安全考虑我们的接口并不希望对外公开.这个时候就需要使用授权(Authorization)机制. 授权过程验证您是否具有访问服务器所需数据的权限. 当发送请 ...
- 16.ajax_case08
# 抓取简书博客总阅读量 # https://www.jianshu.com/u/130f76596b02 import requests import json import re from lxm ...
- Stern-Brocot Tree、伪.GCD 副本
Stern-Brocot Tree.伪.GCD 副本 伪.GCD 问题 1:\(f(a,b,c,n) = \sum_{i=0}^{n} [\frac{ai+b}{c}]\) Case 1: \(a\g ...
- 侧滑关闭Activity的解决方案——SwipeBackLayout
项目地址:ikew0ng/SwipeBackLayout: An Android library that help you to build app with swipe back gesture. ...
- JS获取url参数,修改url参数
function getURL(){ var args = {}; var query = location.search.substring(1); //获得了当前链接的中?号后的参数 var pa ...
- Luogu P2827 蚯蚓(模拟)
P2827 蚯蚓 题意 题目描述 本题中,我们将用符号\(\lfloor c\rfloor\)表示对\(c\)向下取整,例如:\(\lfloor 3.0\rfloor =\lfloor 3.1\rfl ...