Hive map task 处理缓慢

工作中有时也会碰到一些简单的 SQL 但却跑的很慢,
比如根据需求格式拼接 json :


select uid, concat('{',
concat('"login_count_30d":"',if(login_count_30d is null,'',login_count_30d), '",'),
..)
from table_1

SQL 很简单, 就是 from select, 那为什么很慢呢 ?

原因

原因是

  1. 上游的文件大小不均, 有的大, 有的小.
  2. mapper 处理的 inputSplit 的大小不均,
    而且某些 inputSplit 对应的 mapper 任务太重,
    拖慢整体任务的最终处理时间, 其他已完成的任务都在等待.

优化

上游的产出我们一般无法控制, 所以优化方法是:
修改参数, 调整 mapper 任务要处理的 inputSplit 大小.
默认 mapreduce.input.fileinputformat.split.maxsize 是 blockSize,
如果这个 size 对应的 mapper 处理起来比较慢, 可以调低这个数值,
减少单个 mapper 的压力, 同时增加 mapper 数量, 加速任务处理.

例如 maxsize 降低到 30MB:

set mapreduce.input.fileinputformat.split.minsize=10485760;
set mapreduce.input.fileinputformat.split.maxsize=31457280;

重新执行 SQL 后, 在日志可以看到 number of splitsnumber of mappers 的变化.
在 Web DashBoard 上看, 每个 map task 的最大耗时也会比较均衡了.

BTW, 在这里可以看到一些 Deprecated Properties :

mapred.min.split.size 改为了 mapreduce.input.fileinputformat.split.minsize
mapred.max.split.size 改为了 mapreduce.input.fileinputformat.split.maxsize

参考