我有一个火花流应用程序,可以从流中编写拼花数据。
sqlContext.sql(
"""
|select
|to_date(from_utc_timestamp(from_unixtime(at), 'US/Pacific')) as event_date,
|hour(from_utc_timestamp(from_unixtime(at), 'US/Pacific')) as event_hour,
|*
|from events
| where at >= 1473667200
""".stripMargin).coalesce(1).write.mode(SaveMode.Append).partitionBy("event_date", "event_hour","verb").parquet(Config.eventsS3Path)
这段代码每小时运行一段时间,但随着时间的推移,对镶木地板的写作速度已经放缓。当我们开始时花了15分钟来写数据,现在需要40分钟。对于该路径中存在的数据而言,这需要时间。我尝试将相同的应用程序运行到新位置并且运行速度很快。
我已禁用schemaMerge和摘要元数据:
sparkConf.set("spark.sql.hive.convertMetastoreParquet.mergeSchema","false")
sparkConf.set("parquet.enable.summary-metadata","false")
使用spark 2.0
答案 0 :(得分:1)
我遇到过这个问题。追加模式可能是罪魁祸首,因为随着镶木地板文件的大小增加,追加位置会花费越来越多的时间。
我发现解决此问题的一个解决方法是定期更改输出路径。然后,合并和重新排序来自所有输出数据帧的数据通常不是问题。
def appendix: String = ((time.milliseconds - timeOrigin) / (3600 * 1000)).toString
df.write.mode(SaveMode.Append).format("parquet").save(s"${outputPath}-H$appendix")
答案 1 :(得分:0)
这可能是由于追加模式。在这种模式下,应该使用与现有文件不同的名称生成新文件,因此spark每次都会在s3中列出文件(速度很慢)。
我们还设置了parquet.enable.summary-metadata有点不同:
javaSparkContext.hadoopConfiguration().set("parquet.enable.summary-metadata", "false");
答案 2 :(得分:0)
尝试将数据帧写入EMR HDFS(hdfs:// ...),然后使用s3-dist-cp将数据从HDFS上传到S3。 为我工作。