Hive优化系列之Map与Reduce数量选择

注意,以下操作都是针对非分桶表

map数量

  • 算法
    • MapTask的个数=输入文件总大小/分片尺寸,个人理解就是输出的文件数量
      • 原因:系统对输入的源文件依照Block的尺寸分片,并在执行Job时安排一个Map Task处理一个Block的
    • 或者由mapred.map.task数量决定,但是如果这个参数不合理的话,会失效
    • 小文件不分片
    • 压缩文件无法被切分
  • 优化建议
    • 优化原因
      • map数量过少则导致并发度减小,job过长;若大量作业,则会堵塞
    • 减小map数量:合并小文件(hive0.7之后会自动合并) ,是优化的策略
      • map阶段会输出过多小文件,而初始化和创建map的开销很大,在 block 数据量偏少的情况下,单个任务运行的时间就少,那么任务开启的开销很可 能占据总开销的大量比例
      • 如果已知数据源中小文件过多,用户最好在向新表导入数据之前就打开automerge 开关,使一个 Task 处理多个 block。因为同属一个 Task 的结果将被返回在同一个文件中,因此导入数据时做任务的合并处理可达到小文件合并效果。然后关闭automerge 开关,今后都不用再对该表开启
      • 除了检查 block 的大小,还可以通过在 4040 端口查看任务第一阶段 Tasks 的数量和每Task 的运行时间判断是否需要 automerge
      • 第一阶段的 Task 负责 Map 端任务,默认每个Task 对应一个 block,所以如果第一阶段 Task 过多而且单个执行时间短,表示小体积 block 多,Task 运行效率低,需要启用 automerge。注意,不建议为每个线程安排过多的 block。 在调整相关参数时注意,所设计的下限要尽量保证单个 Task 的处理时间不要低于 2s,调 整的上线不能使对应的
      • 合并之后的大小最好控制在 256M以内,能实现较好的性能(这只是个参 考值,具体情况需根据实际数据量和列数而定)
      • 查看实际运行时 GC的状况,如果大部分 Tasks的 GC时间占Task运行时间的 15%以内,可以合并的更多一些。GC时间可以在 4040界面观察
      •  查看每个Task的执行时间,最好不要超过2分钟。如果太长,很可能 会产生 GC问题和拖尾效应,即某个 Task过长而导致的整体运行时间 过长。这时应适当增加 Task
      • 选取 automerge参数时,在设计下限的时候,尽量保证单个 Task 的处理时间不要低于 2s
    • 增加map数量:上一个job的reduce
reduce数量
  • 过少:如果数据量很大,会导致这个reduce异常的慢,从而导致这个任务不能结束,也有可能会OOM
  • 过多:产生的小文件太多,合并起来代价太高,namenode的内存占用也会增大。如果我们不指定mapred.reduce.tasks, hive会自动计算需要多少个reducer
  • 由map端数据复制到Reduce端的数据大小决定
  • 有很多任务是没有reduce的过程的
  • 可以通过设置mapred.reduce.task来控制reduce数
  • Hive的估计机制很弱,不指定reducer个数的情况下,Hive会猜测确定一个reducer个数,基于以下两个设定:
    • 1. hive.exec.reducers.bytes.per.reducer(默认为1000^3)
      • 这个参数控制一个job会有多少个reducer来处理,依据的是输入文件的总大小。默认1GB
    • 2. hive.exec.reducers.max(默认为999)
      • 如果 input / bytes per reduce > max  则会启动这个参数所指定的reduce个数。  这个并不会影响mapre.reduce.tasks参数的设置
  • 计算reducer数的公式很简单:N=min(参数2,总输入数据量/参数1)
  • 通常情况下,有必要手动指定reducer个数。考虑到map阶段的输出数据量通常会比输入有大幅减少,因此即使不设定reducer个数,重设参数2还是必要的。依据Hadoop的经验,可以将参数2设定为0.95*(集群中TaskTracker个数)
  • 通常(不是绝对),大表 JOIN或者 GROUPBY后,产生的数据量相对原始数据小很多。这时可以减少后面 ReduceTask的数目,使 Reduce Task的启动 更有价值
  • 针对 GROUP BY、JOIN、INRTERSACT、EXCEPT、EXTRACT 这五个操作,改变两个 Task数目比例分别对应的语句:
    • SEThive.groupby.aggregateratio=0.6;
    • SEThive.join.aggregateratio=1.0;
    • SEThive.intersect.aggregateratio=1.0;
    • SEThive.except.aggregateratio=1.0;
    • SEThive.extract.aggregateratio=1.0;
小文件过多时参数设置
  • set ngmr.partition.automerge=true;
  • set ngmr.partition.mergesize.mb=-1
    • 合并以后每个task最多处理的数据量大小,-1表示关闭该参数
    • 默认8M;优先级大于ngmr.partition;mergesize
    • 设置一个Block大小,单位MB,-1默认不执行
    • 可以根据任务设置大小,比如200、300等
  • set ngmr.partition.mergesize=3;
    • 表示将 n 个 block 安排给单个线程处理
    • 参数3代表当前3个tasks合并成一个task
    • 可以根据需要仅设置这两个参数(mergesize.mb)其中之一,默认使用方法 mergesize.mb来控制
    • 如果需要使用方法 mergesize,需要将 mergesize.mb 设为-1。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章