Hive、SparkSQL是如何决定写文件的数量的?

1. Hive

1.1 without shuffle

Hive在通过SQL写文件是通过MapReduce任务完成的,如下面这个例子:

在表中插入数据后,可以hdfs对应路径下找到存储的文件

可以看到插入生成了1个文件,这是因为每一条插入语句都会单独启动一个MapReduce任务,一个MapReduce任务对应一个结果文件。

1.2 with shuffle

当插入过程有shuffle时:

由Hive实现group by的过程可知,group by的时候会以group by的字段为key进行shuffle,即上例中的game_id字段。从执行日志中可以看到整个任务启用了62个mapper和1个reducer,由于最终写数据的过程是在reducer中完成,所以最终写数据的文件数量也应该只有1个。

注:Hive控制reducer数量的规则如下:

Hive自己如何确定reduce数:

Spark SQL

2.1 without shuffle

Spark SQL也可以在hive中操作文件,执行命令

Hdfs中文件的存储如下:

可以发现即使是同一条语句,spark也会启动两个任务区并行的写文件,最终产生了两个文件结果。

2.2 with shuffle

Spark中同样以类似的SQL为例:

与Hive不同的是,Spark在执行shuffle过程的时候,会为每一个shuffle的key启动一个任务来写数据,上例中的key game_id在源数据source_table的分布情况是共有26个不同的key。

因此spark会启动26个任务来写数据,在最终的结果文件中也应该有26个文件:

2.3 解决小文件问题

由于spark的写文件方式,会导致产生很多小文件,会对NameNode造成压力,读写性能变差,为了解决这种小文件问题,spark新的版本(笔者使用2.4.0.cloudera2版本)中支持了动态规划shuffle过程,需要配置spark.sql.adaptive.enabled属性。

在将spark.sql.adaptive.enabled属性设置为true后,spark写文件的结果为

从结果可以看到只有一个文件,这是由于动态规划的作用,在写文件的时候只启动了一个任务。动态规划的细节请参考Adaptive Execution 让 Spark SQL 更高效更智能。

–END–

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容