从前面的三篇《小文件问题》、《Hive中Reduce个数是如何计算的》、《map和reduce个数的设定》中大概知道了小文件是如何产生的,以及如何解决它,这篇文章就从Hive的两个黑科技 concatenate关键字和distribute by关键字 彻底解决MapReduce过程中小文件带来的问题
concatenate
如果hive表使用orc格式进行存储,那么能够通过concatenate
命令小文件合并,并且能够节省80%以上的存储空间
经过测试concatenate既能合并分区表,也能合并非分区表,但是使用concatenate
命令合并小文件时不能指定合并后的文件数量,虽然可以多次执行该命令,但显然不够优雅。当多次使用concatenate
后文件数量不在变化,这个跟参数mapreduce.input.fileinputformat.split.minsize=256mb
的设定有有有关,可设定每个文件的最小size。
#对于非分区表 |
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; |
注意:
- distribute by的分区规则是根据分区字段的hash码与reduce的个数进行模除后,余数相同的分到一个区。
- Hive要求distribute by语句要写在sort by语句之前。