问题描述
从spark查出来数据后可以再次保存到hive中。当数据量不是很大的时候,为了避免产生过多小文件,可以使用重分区来解决。
重分区有两个方法:coalesce 和 repartition 。本文重点不是介绍这两个方法,所以大概说一下区别:coalesce 不需要shuffle, 而 repartition 需要 shuffle。而为了避免shuffle,则可以使用coalesce。
当代码如下时:
df.coalesce(1)
.write
.mode(SaveMode.Overwrite)
.saveAsTable("test.test")
即使executor的内存远远大于数据量时,有时仍然会报错: Unable to acquire xxx bytes of memory
我的情况是:executor内存是32G,核是8个,聚合后的数据量大概是50M左右,但是仍然出现了上述的错误。但可以肯定的是,不是内存不够了。
解决办法
经过查证,coalesce在参数过小时(例如1), 并行度不够,所以只会在很少的节点上运行。
而repartition(1)虽然会加入shuffle步骤,但是上游的分区会并行执行。
所以只要将代码中的coalesce(1)改为repartition(1)即可。
df.repartition(1)
.write
.mode(SaveMode.Overwrite)
.saveAsTable("test.test")