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–








暂无评论内容