多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
**Map 数的决定因素有哪些?** 通常情况下,作业会通过 input 的目录产生一个或者多个 map 任务。主要的决定因素有: * input 的文件总个数 * input 的文件大小 * 集群设置的文件块大小。 **是不是设置 map 数越多越好?** 答案是否定的。 如果一个任务有很多小文件(远远小于块大小 128m),则每个小文件也会被当做一个块,用一个 map 任务来完成,而一个 map 任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的 map 数是受限的。 <br/> **是不是保证每个 map 处理接近 128m 的文件块,就没问题了?** 答案也是不一定。 比如有一个 127m 的文件,正常会用一个 map 去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果 map 处理的逻辑比较复杂,用一个 map 任务去做,肯定也比较耗时。 <br/> 针对上面的问题 2 和 3,我们需要采取两种方式来解决:即减少 map 数和增加 map 数。 <br/> **1.小文件进行合并,减少 map 数(默认开启)** 在 map 执行前合并小文件,减少 map 数。 CombineHiveInputFormat 具有对小文件进行合并的功能(系统默认的格式)。 ```sql -- 一以下单位都是Byte,100000000就是100MB -- 下面这三个参数组合在一起的意思是: -- 如果文件大于block(128MB)则按照128MB切割; -- 如果100<block<128,则按照100MB切割; -- 剩余小文件以及分割后剩余的数据小于100MB则安装100MB分割 set mapred.max.split.size=100000000; set mapred.min.split.size.per.node=100000000; set mapred.min.split.size.per.rack=100000000; -- 在执行前将小文件合并 set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 计算公式:当结果大于blocksize时就会减少Map,当小于blocksize时就是增加Map. computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M ``` 注意:HiveInputFormat 没有对小文件合并功能。 <br/> **2.复杂文件增加 Map 数** 当 input 的文件都很大,任务逻辑复杂,map 执行非常慢的时候,可以考虑增加 Map 数,来使得每个 map 处理的数据量减少,从而提高任务的执行效率。 MapReduce 中没有办法直接控制 map 数量,可以通过设置每个 map 中处理的数据量进行设置。 增加 map 的方法为:根据下面的公式,调整 maxSize 最大值: ``` computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M ``` 让 maxSize 最大值低于 blocksize 就可以增加 map 的个数。