web-dev-qa-db-ja.com

データフレームをローカルファイルシステムに保存すると、結果が空になります

AWW EMRでspark 2.3.0を実行しています。次のDataFrame "df"は空ではなく、適度なサイズです:

scala> df.count
res0: Long = 4067

次のコードは、dfhdfsに書き込むのに適しています。

   scala> val hdf = spark.read.parquet("/tmp/topVendors")
hdf: org.Apache.spark.sql.DataFrame = [displayName: string, cnt: bigint]

scala> hdf.count
res4: Long = 4067

ただし、同じコードを使用してローカルparquetまたはcsvファイルに書き込むと、結果は空になります。

df.repartition(1).write.mode("overwrite").parquet("file:///tmp/topVendors")

scala> val locdf = spark.read.parquet("file:///tmp/topVendors")
org.Apache.spark.sql.AnalysisException: Unable to infer schema for Parquet. It must be specified manually.;
  at org.Apache.spark.sql.execution.datasources.DataSource$$anonfun$9.apply(DataSource.scala:207)
  at org.Apache.spark.sql.execution.datasources.DataSource$$anonfun$9.apply(DataSource.scala:207)
  at scala.Option.getOrElse(Option.scala:121)

失敗の理由がわかります。

 ls -l /tmp/topVendors
total 0
-rw-r--r-- 1 hadoop hadoop 0 Jul 30 22:38 _SUCCESS

したがって、no寄木細工のファイルが書き込まれます。

私はこれを20回ほど試しましたが、csvparquetの両方と、2つの異なるEMRサーバーで:すべての場合に同じ動作が見られます。

これはEMR固有のバグですか?より一般的なEC2バグ?他に何か?このコードは、sparkmacosで機能します。

重要な場合-バージョン情報は次のとおりです。

Release label:emr-5.13.0
Hadoop distribution:Amazon 2.8.3
Applications:Spark 2.3.0, Hive 2.3.2, Zeppelin 0.7.3
11
javadba

これはバグではなく、予想される動作です。 Sparkは、非分散ストレージへの書き込みを実際にサポートしていません(共有ファイルシステムがあるため、localモードで動作します)。

ローカルパスは、ドライバー上のパス(これはデータの収集が必要)として(のみ)解釈されるのではなく、各エグゼキューター上のローカルパスとして解釈されます。したがって、各エグゼキューターは独自のチャンクを独自のローカルファイルシステムに書き込みます。

出力は読み戻せないだけでなく(各エグゼキューターとドライバーがデータをロードするために、ファイルシステムの同じ状態を確認する必要があります)、コミットアルゴリズムによっては、ファイナライズされないこともあります(一時ディレクトリから移動します)。

7
user6910411

このエラーは通常、空のディレクトリを寄木細工として読み取ろうとしたときに発生します。 DataFrameが書き込む前に、outcome.rdd.isEmpty()でDataFrameが空かどうかを確認できます。 2.指定したパスが正しいかどうかを確認します

また、どのモードでアプリケーションを実行していますか?クラスターモードで実行している場合は、クライアントモードで実行してください。

0
geekay2015