解决小文件引出的控制map、reduce数量的总结

从前面的三篇《小文件问题》、《Hive中Reduce个数是如何计算的》、《map和reduce个数的设定》中大概知道了小文件是如何产生的,以及如何解决它,这篇文章就从Hive的两个黑科技 concatenate关键字和distribute by关键字 彻底解决MapReduce过程中小文件带来的问题

concatenate

如果hive表使用orc格式进行存储,那么能够通过concatenate命令小文件合并,并且能够节省80%以上的存储空间

经过测试concatenate既能合并分区表,也能合并非分区表,但是使用concatenate命令合并小文件时不能指定合并后的文件数量,虽然可以多次执行该命令,但显然不够优雅。当多次使用concatenate后文件数量不在变化,这个跟参数mapreduce.input.fileinputformat.split.minsize=256mb的设定有有有关,可设定每个文件的最小size。

#对于非分区表
alter table A concatenate;

#对于分区表
alter table B partition(day=20201224) concatenate;

distribute by

在有些情况下,我们需要控制某个特定行应该到哪个reduce,通常是为了进行后续的聚集操作,又或者是为了让数据均衡的进入每一个reduce,保证文件的大小在一个水平上。distribute by子句可以做这件事。distribute by类似MR中partition(自定义分区),进行分区,通常结合sort by使用。

在使用distribute by之前,我们默认已经处理好了reduce的个数,不管是通过设置reduce的个数,还是reduce处理字节数的大小,我们使用distribute by的目的是让每个reduce接受比较均衡的数据量。

对于distribute by进行测试,一定要分配多reduce进行处理,否则无法看到distribute by的效果。

案例实操:

hive (default)> set mapreduce.job.reduces=3;
hive (default)> insert overwrite table xx select * from emp distribute by deptno sort by empno desc;

注意:

  1. distribute by的分区规则是根据分区字段的hash码与reduce的个数进行模除后,余数相同的分到一个区。
  2. Hive要求distribute by语句要写在sort by语句之前。
Author: Tunan
Link: http://yerias.github.io/2021/06/21/hive/29/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.