我试图DataFrame用Parquet格式保存到HDFS,使用DataFrameWriter三列值进行分区,如下所示:
dataFrame.write.mode(SaveMode.Overwrite).partitionBy("eventdate", "hour", "processtime").parquet(path)
Run Code Online (Sandbox Code Playgroud)
正如提到的这个问题,partitionBy将在删除分区的全部现有层次path,并在分区取而代之dataFrame.由于特定日期的新增量数据将定期出现,我想要的是仅替换层次结构中dataFrame具有数据的那些分区,而保持其他分区不变.
要做到这一点,似乎我需要使用其完整路径单独保存每个分区,如下所示:
singlePartition.write.mode(SaveMode.Overwrite).parquet(path + "/eventdate=2017-01-01/hour=0/processtime=1234567890")
Run Code Online (Sandbox Code Playgroud)
但是我无法理解将数据组织到单分区中DataFrame的最佳方法,以便我可以使用它们的完整路径将它们写出来.一个想法是这样的:
dataFrame.repartition("eventdate", "hour", "processtime").foreachPartition ...
Run Code Online (Sandbox Code Playgroud)
但foreachPartition操作上Iterator[Row]是不理想的写出来镶木格式.
我还考虑使用a select...distinct eventdate, hour, processtime获取分区列表,然后按每个分区过滤原始数据帧并将结果保存到完整的分区路径.但是,每个分区的独特查询加过滤器似乎效率不高,因为它会进行大量的过滤/写入操作.
我希望有一种更简洁的方法来保留dataFrame没有数据的现有分区?
谢谢阅读.
Spark版本:2.1