Spark SQL Overwrite问题

背景:

对Hive数据去重更新到原表, beeline中可以直接overwrite.

但是spark.sql中报错: Cannot overwrite a path that is also being read from.;

解决方案:

经过研究, 发现spark.sql 貌似不能直接overwrite, 需要先到临时表再导回原表, 代码如下.

//将结果保存在临时表中    
spark.sql("select ....").write.mode(SaveMode.Overwrite).saveAsTable("tmp_tab")
//将临时表覆盖结果表
spark.table("tmp_tab").write.mode(SaveMode.Overwrite).saveAsTable("result_tab")

原因

hive处理数据的时候,底层走的是mapreduce,mapreduce框架的一个特点是中间数据落盘,即数据map阶段在经过环形缓冲区后会写入磁盘,后续的reduce阶段从磁盘拉取数据,我们可以看到这是有一个落盘的操作。

spark在经过map后数据是放在缓存的,没有落盘的操作,后续的reduce操作是从内存拉取数据。

hive在覆盖写原表的时候,可以看做是会把中间数据落盘,相当于先写到一个临时表然后再写会原表,spark中间数据不会落盘,相当于没有写临时表就直接覆盖原表,所以spark在overwrite原表的时候会报错,而hive不会。

Author: Tunan
Link: http://yerias.github.io/2021/07/17/spark/44/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.