扩展。Reduce 数的设置虽然相较 Map 更灵活,但是也可以像 Map 一样设定一个自动生成
规则,这样运行定时 Job 的时候就不用担心原来设置的固定 Reduce 数会由于数据量的变
化而不合适。
Hive 估算 Reduce 数量的时候,使用的是下面的公式:
[js]view plaincopy
1. num_Reduce_tasks=min[${Hive.exec.Reducers.max},hhh
2. (${input.size}/${Hive.exec.Reducers.bytes.per.R
educer})]
也就是说,根据输入的数据量大小来决定 Reduce 的个数,默认
Hive.exec.Reducers.bytes.per.Reducer 为 1G,而且 Reduce 个数不能超过一个上限参数
值,这个参数的默认取值为 999。所以我们可以调整
Hive.exec.Reducers.bytes.per.Reducer 来设置 Reduce 个数。
设置 Reduce 数同样也是根据运行时间作为参考调整,并且可以根据特定的业务需求、工
作负载类型总结出经验,所以不再赘述。
Map 与 Reduce 之间的优化(Spill,hcopy,hSort
phase)
Map phase 和 Reduce phase 之间主要有 3 道工序。首先要把 Map 输出的结果进行排序后
做成中间文件,其次这个中间文件就能分发到各个 Reduce,最后 Reduce 端在执行
Reduce phase 之前把收集到的排序子文件合并成一个排序文件。这个部分可以调的参数
挺多,但是一般都是不要调整的,不必重点关注。
Spill 与hSort
在 Spill 阶段,由于内存不够,数据可能没办法在内存中一次性排序完成,那么就只能把局
部排序的文件先保存到磁盘上,这个动作叫 Spill,然后 Spill 出来的多个文件可以在最后进
行 merge。如果发生 Spill,可以通过设置 io.Sort.mb 来增大 Mapper 输出 buffer 的大小,
避免 Spill 的发生。另外合并时可以通过设置 io.Sort.factor 来使得一次性能够合并更多的数
据。调试参数的时候,一个要看 Spill 的时间成本,一个要看 merge 的时间成本,还需要注
意不要撑爆内存(io.Sort.mb 是算在 Map 的内存里面的)。Reduce 端的 merge 也是一样
可以用 io.Sort.factor。一般情况下这两个参数很少需要调整,除非很明确知道这个地方是
瓶颈。
Copy