ストリームから寄木細工のデータを書き込むsparkストリーミングアプリケーションがあります。
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)
このコードは1時間ごとに実行されますが、時間の経過とともに寄木細工への書き込みが遅くなります。始めたところ、データの書き込みに15分かかりましたが、今では40分かかります。そのパスに存在するデータに比例して時間がかかります。同じ場所で同じアプリケーションを実行してみましたが、高速に実行されました。
SchemaMergeと要約メタデータを無効にしました:
sparkConf.set("spark.sql.Hive.convertMetastoreParquet.mergeSchema","false")
sparkConf.set("parquet.enable.summary-metadata","false")
spark 2.0を使用
データフレームをEMR HDFS(hdfs:// ...)に書き込んでから、s3-dist-cpを使用してHDFSからS3にデータをアップロードします。私のために働いた。
この問題に遭遇しました。寄せ集めファイルのサイズが大きくなるにつれ、追加モードを見つけるのに時間がかかるという点で、おそらく追加モードが原因です。
これを解決する1つの回避策は、出力パスを定期的に変更することです。すべての出力データフレームからのデータのマージと並べ替えは、通常は問題になりません。
def appendix: String = ((time.milliseconds - timeOrigin) / (3600 * 1000)).toString
df.write.mode(SaveMode.Append).format("parquet").save(s"${outputPath}-H$appendix")
追加モードが原因である可能性があります。このモードでは、既存のファイルとは異なる名前で新しいファイルを生成する必要があるため、sparkは毎回s3(遅い)にファイルをリストします。
また、parquet.enable.summary-metadataの設定も少し異なります。
javaSparkContext.hadoopConfiguration().set("parquet.enable.summary-metadata", "false");