一、场景
目前使用s3替代hdfs作为hive表数据存储,使用spark sql insert数据到hive表,发现一个简单的查询+插入任务,查询+insert的动作显示已经执行完,任务还在跑,直到跑了两个小时后才执行结束。
二、原因
s3对spark默认的commit操作兼容性不强,spark有两种commit操作,一种是commit task,在executor上执行,一种是commit job,在driver上执行。默认commit策略下,spark在输出数据的时,会先输出到临时目录上,临时目录分task临时目录和job临时目录,默认的commit task操作是将执行成功的task的输出数据从task的临时目录rename到job的临时目录task目录,commit job操作则是driver单线程遍历所有job临时目录下所有task目录并rename到用户指定的输出目录下。driver运行时间长在于单线程rename所有task目录,最后在最终输出的目录加上SUCCESS文件,而s3的rename操作是mv=cp+rm,和hdfs的rename操作不同,效率低下。
三、解决
一般情况下,我们使用的committer是FileOutputCommitter,在hadoop2.7后,支持新的commit算法,将mapreduce.fileoutputcommitter.algorithm.version设置为2,默认是1,新的commit算法对commit task做了一下改动,不再将task临时目录mv到job的临时目录下,而是直接移动到最终目录下,不需要driver最后再单线程移动一次,commit job操作是在最终目录下直接加上SUCCESS文件即可。简单概括就是单线程mv变多线程mv,新的commit算法提高了性能,但是降低了数据一致性。
spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version=2
标签:task,s3,单线程,job,spark,commit,Spark,目录
From: https://www.cnblogs.com/xiongmozhou/p/16788971.html