本帖最后由 pig2 于 2014-2-20 00:20 编辑 阅读本文能够带着下面问题: 1.map和reduce的数量过多会致使什么状况? 2.Reduce能够经过什么设置来增长任务个数? 3.一个task的map数量由谁来决定? 4.一个task的reduce数量由谁来决定? 通常状况下,在输入源是文件的时候,一个task的map数量由splitSize来决定的,那么splitSize是由如下几个来决定的 goalSize = totalSize / mapred.map.tasks inSize = max {mapred.min.split.size, minSplitSize} splitSize = max (minSize, min(goalSize, dfs.block.size)) 一个task的reduce数量,由partition决定。 在输入源是数据库的状况下,好比mysql,对于map的数量须要用户本身指定,好比 jobconf.set(“mapred.map.tasks.nums”,20); 若是数据源是HBase的话,map的数量就是该表对应的region数量。 map和reduce是hadoop的核心功能,hadoop正是经过多个map和reduce的并行运行来实现任务的分布式并行计算,从这个观点来看,若是将map和reduce的数量设置为1,那么用户的任务就没有并行执行,可是map和reduce的数量也不能过多,数量过多虽然能够提升任务并行度,可是太多的map和reduce也会致使整个hadoop框架由于过分的系统资源开销而使任务失败。因此用户在提交map/reduce做业时应该在一个合理的范围内,这样既能够加强系统负载匀衡,也能够下降任务失败的开销。 1 map的数量 map的数量一般是由hadoop集群的DFS块大小肯定的,也就是输入文件的总块数,正常的map数量的并行规模大体是每个Node是10~100个,对于CPU消耗较小的做业能够设置Map数量为300个左右,可是因为hadoop的每个任务在初始化时须要必定的时间,所以比较合理的状况是每一个map执行的时间至少超过1分钟。具体的数据分片是这样的,InputFormat在默认状况下会根据hadoop集群的DFS块大小进行分片,每个分片会由一个map任务来进行处理,固然用户仍是能够经过参数mapred.min.split.size参数在做业提交客户端进行自定义设置。还有一个重要参数就是mapred.map.tasks,这个参数设置的map数量仅仅是一个提示,只有当InputFormat 决定了map任务的个数比mapred.map.tasks值小时才起做用。一样,Map任务的个数也能经过使用JobConf 的conf.setNumMapTasks(int num)方法来手动地设置。这个方法可以用来增长map任务的个数,可是不能设定任务的个数小于Hadoop系统经过分割输入数据获得的值。固然为了提升集群的并发效率,能够设置一个默认的map数量,当用户的map数量较小或者比自己自动分割的值还小时可使用一个相对交大的默认值,从而提升总体hadoop集群的效率。 2 reduece的数量 reduce在运行时每每须要从相关map端复制数据到reduce节点来处理,所以相比于map任务。reduce节点资源是相对比较缺乏的,同时相对运行较慢,正确的reduce任务的个数应该是0.95或者1.75 *(节点数 ×mapred.tasktracker.tasks.maximum参数值)。若是任务数是节点个数的0.95倍,那么全部的reduce任务可以在 map任务的输出传输结束后同时开始运行。若是任务数是节点个数的1.75倍,那么高速的节点会在完成他们第一批reduce任务计算以后开始计算第二批 reduce任务,这样的状况更有利于负载均衡。同时须要注意增长reduce的数量虽然会增长系统的资源开销,可是能够改善负载匀衡,下降任务失败带来的负面影响。一样,Reduce任务也可以与 map任务同样,经过设定JobConf 的conf.setNumReduceTasks(int num)方法来增长任务个数。 3 reduce数量为0 有些做业不须要进行归约进行处理,那么就能够设置reduce的数量为0来进行处理,这种状况下用户的做业运行速度相对较高,map的输出会直接写入到 SetOutputPath(path)设置的输出目录,而不是做为中间结果写到本地。同时Hadoop框架在写入文件系统前并不对之进行排序。 推荐阅读: hadoop中map和reduce的数量设置 在 Hadoop 上编写 MapReduce 程序 |