一个输入分片( in put split)就是可以被单个map 操作 处理的输入块. 每个map 操作仅仅处理一个输入分片,而且一个一个地处理每条记录,也就是一个键/值对。输入分片和记录都是逻辑上的,并不必要将它们相应到文件(尽管普通情况下都是这种)。
在数据库中. 一个输入分片能够是一个表 的若干行,而一条记录就是这若干行中的一行(其实DBlnputFormat 就是这么
的。它是一种能够从关系数据库获取数据的一种格式).
①JobClient通过指定的输入文件的格式来生成数据分片InputSplit。
②一个分片不是数据本身,而是可分片数据的引用(你要用它的时候,依据他的应用地址。就找到了原始文件数据);一个InputSplit 有一个以字节为单位的长度以及一组存储位置(即一组主机名).存储位置是为了让 MapReduce
系统将map 操作放在离存储位置近期的机上,而长度是为了将单元 排序以使得最大的单元可以最先得到处理。以提高效率(这也是一种贪心近似算法) 。
③InputFormat接口负责生成分片。
源代码位置:org.apache.hadoop.mapreduce.lib.input包(新), org.apache.hadoop.mapred.lib
包(旧)
查看当中FileInputFormat类中的getSplits()方法;
computeSplitSize()函数决定分片大小;
JobClient 调用getSplits() 方法,并以numSplits(如上图所看到的,新api传入的上下文,自然是能够的,必定含有切割的全部须要的数据) 为參数传入期望的map 任务 数。这个參数将作为一个參考值. InputFormat能够返回一个不同于这个值个数的单元。在计算好实际的分布的个数后,client将它们发送到jobtracker
上. jobtracker 会使用它们的存储位置信息将它们调度到对应的tasktracker 上运行。
在tasktracker 上, map 任务会将输入分片传递到InputFormat 的 getRecordReader() 方法中从而获得对应的RecordReader. RecordReader 基本就是记录上的迭代器,map 任务会使用RecordReader 来读取记录而且生成键/值对,然后再传递给map 函数.
请看Mapper’s run()方法:
当运行了setup(),nextKeyValue()会被上下文反复调用。当全部的split记录遍历之后。map运行cleanup()。
这边是分片输入的相关知识。
各种输入类的结构关系图: