本文主要是介绍MapReduce输入输出,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
MapReduce输入输出
作业的输入
InputFormat 为Map/Reduce作业描述输入的细节规范。
Map/Reduce框架根据作业的 InputFormat 来:
- 检查作业输入的有效性。
- 把输入文件切分成多个逻辑 InputSplit 实例, 并把每一实例分别分发给一个 Mapper 。
- 提供 RecordReader 的实现,这个RecordReader从逻辑 InputSplit 中获得输入记录, 这些记录将由 Mapper 处理。
基于文件的 InputFormat 实现(通常是 FileInputFormat 的子类) 默认行为是按照输入文件的字节大小,把输入数据切分成逻辑分块( logical InputSplit )。 其中输入文件所在的 FileSystem 的数据块尺寸是分块大小的上限。下限可以设置mapred.min.split.size 的值。
考虑到边界情况,对于很多应用程序来说,很明显按照文件大小进行逻辑分割是不能满足需求的。 在这种情况下,应用程序需要实现一个 RecordReader 来处理记录的边界并为每个任务提供一个逻辑分块的面向记录的视图。
TextInputFormat 是默认的 InputFormat 。
如果一个作业的 Inputformat 是 TextInputFormat , 并且框架检测到输入文件的后缀是 .gz 和 .lzo ,就会使用对应的 CompressionCodec 自动解压缩这些文件。 但是需要注意,上述带后缀的压缩文件不会被切分,并且整个压缩文件会分给一个mapper来处理。
InputSplit
InputSplit 是一个单独的 Mapper 要处理的数据块。
一般的 InputSplit 是字节样式输入,然后由 RecordReader 处理并转化成记录样式。
FileSplit 是默认的 InputSplit 。 它把 map.input.file 设定为输入文件的路径,输入文件是逻辑分块文件。
RecordReader
RecordReader 从 InputSlit 读入 <key, value> 对。
一般的, RecordReader 把由 InputSplit 提供的字节样式的输入文件,转化成由Mapper 处理的记录样式的文件。 因此 RecordReader 负责处理记录的边界情况和把数据表示成keys/values对形式。
作业的输出
OutputFormat 描述Map/Reduce作业的输出样式。
Map/Reduce框架根据作业的 OutputFormat 来:
- 检验作业的输出,例如检查输出路径是否已经存在。
- 提供一个 RecordWriter 的实现,用来输出作业结果。 输出文件保存在FileSystem 上。
TextOutputFormat 是默认的 OutputFormat 。
任务的Side-Effect File
在一些应用程序中,子任务需要产生一些side-file,这些文件与作业实际输出结果的文件不同。
在这种情况下,同一个 Mapper 或者 Reducer 的两个实例(比如预防性任务)同时打开或者写 FileSystem 上的同一文件就会产生冲突。因此应用程序在写文件的时候需要为每次任务尝试(不仅仅是每次任务,每个任务可以尝试执行很多次)选取一个独一无二的文件名(使用attemptid,例如task_200709221812_0001_m_000000_0 )。
为了避免冲突,Map/Reduce框架为每次尝试执行任务都建立和维护一个特殊的 ${mapred.output.dir}/_temporary/_${taskid} 子目录,这个目录位于本次尝试执行任务输出结果所在的 FileSystem 上,可以通过 ${mapred.work.output.dir} 来访问这个子目录。 对于成功完成的任务尝试,只有${mapred.output.dir}/_temporary/_${taskid} 下的文件会 移动 到${mapred.output.dir} 。当然,框架会丢弃那些失败的任务尝试的子目录。这种处理过程对于应用程序来说是完全透明的。
在任务执行期间,应用程序在写文件时可以利用这个特性,比如 通过 FileOutputFormat.getWorkOutputPath()获得 ${mapred.work.output.dir} 目录, 并在其下创建任意任务执行时所需的side-file,框架在任务尝试成功时会马上移动这些文件,因此不需要在程序内为每次任务尝试选取一个独一无二的名字。
注意:在每次任务尝试执行期间, ${mapred.work.output.dir} 的值实际上是 ${mapred.output.dir}/_temporary/_{$taskid} ,这个值是Map/Reduce框架创建的。 所以使用这个特性的方法是,在 FileOutputFormat.getWorkOutputPath() 路径下创建side-file即可。
对于只使用map不使用reduce的作业,这个结论也成立。这种情况下,map的输出结果直接生成到HDFS上。
RecordWriter
RecordWriter 生成 <key, value> 对到输出文件。
RecordWriter的实现把作业的输出结果写到 FileSystem 。
这篇关于MapReduce输入输出的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!