1 优化说明
Hive的计算任务由MapReduce完成,并行度调整分为Map端和Reduce端。
1.1 Map端并行度
Map端的并行度及Map的个数,由输入文件的切片数决定,一般情况下Map端并行度不需要手动调整。
在特殊情况下(查询的表中存在大量小文件、map端有复杂的查询逻辑)可以考虑手动调整。
1、查询的表中存在大量小文件
Hadoop默认切片策略,一个小文件会单独启动一个map task负责计算。如果查询表中存在大量小文件,会启动大量map task,造成资源浪费。
解决:
使用HIve提供的CombineHiveInputFormat,把多个小文件合并为一个切片,控制map task个数。
相关参数:
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
2、map端有复杂的查询逻辑
当SQL语句中有正则替换、json解析等复杂耗时的查询逻辑时,map端的计算会相对慢一些。
解决:
在计算资源充足的情况下,可考虑增大map端的并行度,令map task多一些,每个map task计算的数据少一些。
相关参数:
--一个切片的最大值
set mapreduce.input.fileinputformat.split.maxsize=256000000;
1.2 Reduce端并行度
Reduce端的并行度即Reduce个数可由用户自己决定,也可由Hive自行根据MR Job输入的文件大小估算。
相关参数:
--指定Reduce端并行度,默认值为-1,表示用户未指定
set mapreduce.job.reduces;
--Reduce端并行度最大值
set hive.exec.reducers.max;
--单个Reduce Task计算的数据量,用于估算Reduce并行度
set hive.exec.reducers.bytes.per.reducer;
Reduce端并行度的确定逻辑如下:
若指定参数mapreduce.job.reduces的值为一个非负整数,则Reduce并行度为指定值。否则,Hive自行估算Reduce并行度,估算逻辑如下:
(1)假设Job输入的文件大小为totalInputBytes;
(2)参数hive.exec.reducers.bytes.per.reducer的值为bytesPerReducer;
(3)参数hive.exec.reducers.max的值为maxReducers;
则Reduce端的并行度为:
Hive自行估算Reduce并行度时,是以整个MR Job输入的文件大小作为依据的。因此,在某些情况下其估计的并行度很可能并不准确,此时就需要用户根据实际情况来指定Reduce并行度了。
2 案例
1、示例SQL语句
select
province_id,
count(*)
fromorder_detail
groupby province_id;
2、优化前
在不指定Reduce并行度时,Hive自行估算并行度的逻辑如下:
totalInputBytes=1136009934
bytesPerReducer=256000000
maxReducers=1009
Reduce并行度为:
3、优化思路
在默认情况下,是会进行map-side聚合的,也就是Reduce端接收的数据,实际上是map端完成聚合之后的结果。
观察yarn中任务的执行过程,会发现,每个map端输出的数据只有34条记录,共有5个map task。也就是说Reduce端实际只会接收170(34*5)条记录,故理论上Reduce端并行度设置为1就足够了。这种情况下,用户可通过以下参数,自行设置Reduce端并行度为1。
--指定Reduce端并行度,默认值为-1,表示用户未指定
set mapreduce.job.reduces=1;