hive中的启动的map数据量,以及reduce的数据量,都是由系统给控制的,一般来说,map的数据量是由文件的个数,以及文件量的大小所决定。如果你的文件很多,那么每个文件必然会启动一个map进行处理,或者你的文件非常大,是hdfs中block_size的N倍,那么就会分成N个文件,同样会启动N个map进行处理。而reduce的数据量则是根据你的key多少来决定的,一旦你的map生成的key非常多,那么reduce 的数据量也会比较多,最好避免像order by之类的全局统计参数,因为这类函数通常会只用一个reduce进行处理。
map多和少,reduce多和少的时间差异是很明显的,3个map和30个map的时间差异基本上就是10倍,这就是为什么我们竭尽全力的增加map数,而为了达到这个增加map数的目的,通常有两种途径,一种是尽量增加文件的大小,变成block_size 的N倍,还有一种办法是将大文件拆分为小文件,每个小文件进行处理的时候,都会启动一个map。前者的写法通常如下: create table cajeep_test2 as selecta.*,dummy_string(200) dummy_string from tdl_en_pp_node_stream_tmp2,通过增加的dummy_string的垃圾字段来增加数据文件的大小,从而实现将文件分成多个文件的作用;后者则需要set mapred.reduce.tasks = 30;set hive.merge.mapredfiles=false;,通过这两个设置,让系统每次启动reduce,都会启动30个,同时将reduce生成的文件不进行合并。因为每个reduce都会生成一个文件,光设置还不够,还需要让sql产生reduce的过程,而且是不能全局性的reduce(order by之类的),除非有group by之类能够保证产生多个reduce的代码之外,通常的代码后面都需要加上distribute by rand(123),让其自动产生一个reduce的过程,一旦产生reduce的过程,就会自动调用30个reduce,从而达到生成30个文件的目的。
具体的研究可以看下这篇