Hadoop Mapreduce 中的FileInputFormat类的文件切分算法和host选择算法
文件切分算法
文件切分算法主要用于确定inputsplit的个数以及每个inputsplit对应的数据段。 fileinputformat以文件为单位切分成inputsplit。对于每个文件,由以下三个属性值确定其对应的inputsplit的个数。
- goalsize:根据用户期望的inputsplit数据计算,即totalsize/numsplit。totalsize为文件总大小;numsplit为用户设定的map task个数,默认情况下是1.
- minsize:inputsplit的最小值,由配置参数mapred.min.split.size确定,默认是1.
- blocksize:文件在hdfs中存储的block大小,不同文件可能不同,默认是64mb.
这三个参数共同决定inputsplit的最终大小,计算方式:
splitsize = max{mainsize,min{goalsize,biocksize}}
一旦确定splitsize值后,fileinputformat将文件依次切成大小为splitsize的inputsplit,最后剩下不足splitsize的数据块单独成为一个inputsplit。
host选择算法
inputsplit切分方案确定之后,需要确定每个inputsplit的元数据信息。元数据信息通常由四部分组成:<file,start,length,host>,分别表示inputsplit所在的文件、起始位置、长度以及所在的host(节点)列表。其中,前面三项容易确定,难点在于host列表的选择方法。
hadoop将数据本地性按照代价划分为三个等级:node locality、rack locality和data center locality。在进行任务调度时,会依次考虑这三个节点的locality,即有限让空闲资源处理本节点上的数据,如果节点上没有任何可处理的数据,则处理同一个机架上的数据,最差的情况是处理其他机架上的数据,但是必须位于同一个数据中心。
fileinputformat设计了一个简单有效的启发式算法:首先按照rack包含的数据量对rack进行排序,然后在rack内部按照每个node包含的数据量对node排序,最后取前n个node的host作为inputsplit的host列表,这里的n为block的副本数。当任务调度器调度task时,只要将task调度给位于host列表中的节点,就认为该task满足本地性。
当使用基于fileinputformat实现inputformat时,为了提高map task的数据本地性,应尽量使inputsplit大小与bolck大小相同。