将数据框保存到本地文件系统会导致结果为空

Saving dataframe to local file system results in empty results

我们 运行 spark 2.3.0 AWS EMR。以下 DataFramedf”非空且大小适中:

scala> df.count
res0: Long = 4067

以下代码可以很好地将 df 写入 hdfs:

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

scala> hdf.count
res4: Long = 4067

但是使用相同的代码写入本地 parquetcsv 文件最终得到空结果:

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.apply(DataSource.scala:207)
  at org.apache.spark.sql.execution.datasources.DataSource$$anonfun.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

因此没有 镶木地板文件正在写入。

对于 csvparquet 以及两个不同的 EMR 服务器,我可能已经尝试了二十次:在所有情况下都表现出相同的行为。

这是 EMR 特定的错误吗?一个更普遍的 EC2 错误?还有别的吗?此代码适用于 spark macOS

以防万一 - 这是版本控制信息:

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

当您尝试将空目录读取为 parquet 时,通常会发生此错误。 你可以检查 1. 如果 DataFrame 为空,在写入之前用 outcome.rdd.isEmpty() 。 2.检查你给的路径是否正确

另外,您运行您的应用程序处于什么模式?如果您 运行 在集群模式下,请在客户端模式下尝试 运行 它。

这不是错误,而是预期的行为。 Spark 并不真正支持写入非分布式存储(它将在 local 模式下工作,只是因为你有共享文件系统)。

本地路径不被(仅)解释为驱动程序上的路径(这需要收集数据),而是每个执行程序上的本地路径。因此每个执行者都会将自己的块写入自己的本地文件系统。

不仅输出不可读(要加载数据,每个执行程序和驱动程序应该看到文件系统的相同状态),而且根据提交算法,甚至可能无法最终确定(从临时目录移动) ).