实际上map task的数量依赖于InputFormat的getSplits生成的InputSplit的数量。因此经常使用定制的InputFormat来准确的控制map task的数目。换句话说map的数目依赖于输入的总大小(输入的block数)。基于文件的InputFormat的主要功能就是根据输入文件的总大小将它切分为逻辑上的InputSplit。对于分块的大小,输入文件所在的文件系统的块大小是其上限,下限可以通过mapred.min.split.size来设置。因此如果有10TB的数据且块大小为128M,那么将会产生82000(我算的是81920)个map除非setNumMapTasks(int)设置得更多。(problem:如果map数设为了90000,那么多出来的map干什么了?没有数据了啊!难道什么都不做,待进一步分析)
对于一个合理的并行程度每个节点的map数量应该大约在10-100个(对于不太消耗cpu的map task 可以有300个)。需要注意的是Task的建立是需要时间的,因此在并行度许可的情况下应该使用尽量少的map来运行。
TaskSplitMetaInfo[] splits = createSplits(jobId); if (numMapTasks != splits.length) { throw new IOException("Number of maps in JobConf doesn't match number of " + "recieved splits for job " + jobId + "! " + "numMapTasks=" + numMapTasks + ", #splits=" + splits.length); } numMapTasks = splits.length;
这样看来map的数量与JobConfig的mapred.map.tasks的值没有关系,依据的是split的数目