我使用的是spark 1.6.1,我正试图将数据帧保存为orc格式。
我面临的问题是保存方法非常慢,每个执行器上的50M orc文件大约需要6分钟。这就是我保存数据帧的方式
dt.write.format("orc").mode("append").partitionBy("dt").save(path)
我尝试将saveAsTable用于同样使用orc格式的配置单元表,速度似乎快了20%到50%,但这种方法也有自己的问题——似乎当任务失败时,由于文件已经存在,重试总是会失败。这就是我保存数据帧的方式
dt.write.format("orc").mode("append").partitionBy("dt").saveAsTable(tableName)
保存方法如此缓慢是有原因的吗?我做错什么了吗?
问题是由partitionBy方法引起的。PartitionBy读取指定列的值,然后为分区列的每个值隔离数据。尝试在不分区的情况下保存,会有显著的性能差异。
请参阅我前面关于基数和partitionBy的评论。
如果你真的想对它进行分区,并且它只是一个50MB的文件,那么就使用之类的东西
dt.write.format("orc").mode("append").repartition(4).saveAsTable(tableName)
重分区将创建4个大致相等的分区,而不是在dt列上进行分区,因为这可能会导致写入大量orc文件。
4个分区的选择有点随意。对这样的小文件进行分区不会带来太多性能/并行化方面的好处。读取更多文件的开销是不值得的。
使用save()在特定位置保存可能在某个blob位置。
使用saveAsTable()将数据帧保存为spark SQL表