Spark DataFrame写入CSV文件未生成目标文件问题咨询
看起来你遇到的情况有点反常——明明DataFrame的count显示有48720条数据,但写入后目录里只有_SUCCESS相关文件,完全看不到实际的CSV数据文件。我来帮你梳理几个常见的排查方向和解决办法:
1. 改用Spark内置的CSV数据源(Spark 2.0+适用)
如果你用的是Spark 2.0及以上版本,完全不需要依赖com.databricks.spark.csv这个第三方包了,Spark已经原生支持CSV格式。而且旧的第三方包偶尔会出现兼容性问题,建议把代码改成这样:
println("Total number of reports: " + reportDf.count()) reportDf .coalesce(1) .write .format("csv") .option("header", "true") // 要是需要输出表头就加上这行 .mode("overwrite") // 避免目录已存在导致的写入失败 .save("output/cluster")
这里我把输出路径改成了output/cluster而不是你原来的output/cluster.csv——因为Spark写入分布式文件时,会先创建一个目录,实际的CSV数据会以part-00000-xxxx.csv这类文件名存放在目录里,不是直接生成一个叫cluster.csv的单个文件。之前你写的路径会被当作目录名,这也容易造成混淆。
2. 用repartition(1)替代coalesce(1)
有时候coalesce(1)在某些场景下(比如上游存在宽依赖)不会强制合并分区,可能导致分区数为0,自然就没有数据文件生成。你可以换成repartition(1)试试,它会触发shuffle,但能确保把所有数据合并到一个分区:
reportDf .repartition(1) .write .format("csv") .mode("overwrite") .save("output/cluster")
3. 确认DataFrame中确实存在数据
虽然count()返回了非零值,但Spark是懒执行机制:count()会触发一次计算,后续的write会再次触发计算。如果你的DataFrame依赖的数据源在两次计算之间发生了变化,或者有隐式的过滤逻辑,可能导致写入时数据为空。建议在写入前先打印几条数据验证:
reportDf.show(10) // 打印前10条数据,直观确认数据存在
4. 查看Spark运行日志找线索
你可以去Spark的日志目录(通常是$SPARK_HOME/logs)查看具体的执行日志,看看写入CSV环节有没有报错——比如磁盘空间不足、权限不够,或者数据源读取时出现异常,这些都可能导致数据没有正常落地。
5. 检查输出目录的权限和磁盘空间
确保spark用户对output目录有完整的读写权限,同时用df -h命令检查磁盘剩余空间,要是磁盘满了,也会出现只生成_SUCCESS文件但没有数据的情况。
按照上面的步骤逐一排查,应该能快速定位并解决问题。
内容的提问来源于stack exchange,提问作者Monika

