关于hadoop的maptask数量

今天看hadoop的JobClient的源码,在JobClient的init(JobConfig)函数中当mapred.job.tracker的值为默认值或者"local"时,将JobConfig的mapred.map.tasks设置为了1。觉得是不是太武断了点,不过在看JobConfig.setNumMapTasks(int)的注释时发现是这样说的:
这个MapTask数量的值设置只是对hadoop框架的提示,并不起决定作用。
实际上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的数目

猜你喜欢

转载自youli9056.iteye.com/blog/1663276