对于分布式任务来说,任务执行的并行度十分重要。Hive的底层是MapReduce,所以Hive的并行度优化分为Map端优化和Reduce端优化。
(1)、Map端优化
Map端的并行度与Map切片数量相关,并行度等于切片数量。一般情况下不用去设置Map端的并行度。以下特殊情况下需要设置Map端并行度。
1.1、查询表中存在大量的小文件(减小Map并行度)
一个小文件相当于一个切片,所以就会为每个小文件开启一个maptask任务,因此会启动大量的maptask,造成资源的大量占用。解决问题的办法就是进行小文件的合并,把多个小文件合并成一个大文件,这个大文件作为一个切片,然后给这个大文件开启一个maptask任务即可。合并的操作是CombineHiveInputFormat。相关的参数是:
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
(需要知道使用的是CombineHiveInputFormat操作就可以了,具体的命令用到的时候再查)
1.2、map端有复杂的查询逻辑
若SQL语句中有正则替换、json解析等复杂耗时的查询逻辑时,map端的计算会相对慢一些。为了提高map端的计算速度,在计算资源充足的情况下就可以适当的提高map端的并行度。这是只需要减小每个切片的数据量大小就可以了。相关的参数是:
--------------一个切片的最大值---------------
set mapreduce.input.fileinputformat.split.maxsize=256000000;
(2)、Reduce端优化
Reduce端并行度的确定逻辑是:若指定mapreduce.job.reduces的值为一个非负整数,则reduce并行度为指定的值。否则Hive自行估算Reduce并行度。其估算的逻辑是:
假设Job输入的文件大小为toatlInputBytes,每个Reducer的数据量参数hive.exec.reducers.bytes.per.reducer的值为bytesPerReducer,以及最大Reducer数量参数hive.exec.reducers.max的值为maxReducers。则Reducer端的并行度为:
min(ceil(toatlInputBytes/bytesPerReducer),maxReducers)。
但是在有些情况下,这种估算方式也有不足,因为它是以整个文件大小作为分子进行的估算,合理的应该是进入Reduce端的文件大小来估算,因为整个文件在进入Map端之后可能进行过聚合,那么此时进入Reduce端的数据量就不是整个文件大小。
总结来说:Reduce端的优化就是在于手动的设置并行度的数量,如果未手动设置,则会按照上面的方式来计算并行度。