一 产生原因
1.1 数据增量多批次插入,每批次会产生 partitions*reducetasks 个小文件
1.2 hive或spark 数据分析 reduce task个数过多。
二 解决方法
2.1 hadoop archive
hive> set hive.archive.enabled=true;
hive> set hive.archive.har.parentdir.settable=true;
hive> set har.partfile.size=1099511627776;
alter table table_name archive PARTITION(dt='${DT}');
但是因为从HAR读数据需要额外的开销,因此查询归档下的数据可能会变慢。
且归档的分区不能够INSERT OVERWRITE,必须先unarchive.
2.2 spark coalse()
//1.1将该分区数据抽入临时表
DF.filter(dt)
.coalesce(1)
.write
.mode(SaveMode.Append)
.format("parquet")
.partitionBy("dt")
/**
* 该api不需事先创建表,但是overwrite分区会导致全表被覆盖
*/
.saveAsTable("ykchr.t1");
// 1.2 删除原分区的数据
spark.sql(s"ALTER TABLE t DROP IF EXISTS PARTITION (dt='$dt')");
// 1.3 重新写入分区
DF.write.insertInto("t");
三 最佳实践
一般采用Hadoop Archive将部分历史数据进行归档,需要访问的时候再恢复,将经常用到的或者刚进入的数据通过spark DF.filter(dt).coalse()定时任务合并小文件。