distribute by 是用来办理数据分发题目的,根据指定的分区字段值,可以控制数据分发到对应的reduce中去【HASH的方式,类似于spark中的repartition】。分区编号 =分区字段值的hash值 % reduce数,即【distribute by dt】 操作可以将同一分区的数据直接发到同一个reduce中。
执行sql后,由原来100个分区,每个分区下2000个小文件的局面改造成:100个分区,每个分区下只有一个文件。相关sql如下:
set hive.exec.reducers.bytes.per.reducer=1024*10*1000*1000; ---10G
insert overwrite table test partition(dt)
select *
from table
distribute by rand()
复制代码
(2)rand()函数来控制hdfs上最终天生多少个文件【剧烈推荐】
insert overwrite table test partition(dt)
select *
from table
distribute by cast(rand()*100 as int);
#--cast(rand()*100 as int) 生成 0-100之间的随机整数
复制代码
ps:通过 distribute by cast( rand() * N as int) 来控制落地文件数, 此中 cast( rand() * N as int) 可以天生0-N之间的随机整数。 ps:更多的Hive小文件题目及办理方案见文章:
Hive的小文件题目-CSDN博客文章浏览阅读409次,点赞7次,收藏12次。Hive的小文件题目https://blog.csdn.net/SHWAITME/article/details/136108785
2 思索
上述论述hive动态分区产生小文件的最佳办理方案:distribute by cast( rand() * N as int) = 【distribute by + rand随机数】,两者互相共同,控制数据相对均衡(办理数据倾斜)的发往到指定数量的reducer中,严格控制hdfs上落地文件数目。(HQL)
但是对于利用SparkSQL的用户来说,SparkSQL中的repartition算子可以办理这一题目,repartition和distribute by的作用同等 (控制数据发往指定分区)
spark小文件详细的办理方案待补充~
参考文章:
Hive/Spark小文件办理方案(企业级实战)
Hive Distribute by 应用之动态分区小文件过多题目优化_distribute by cast(rand() * 99 as int)-CSDN博客