Dataframe 作为参数传递的DF不工作,任务不可序列化
使用spark shell测试功能Dataframe 作为参数传递的DF不工作,任务不可序列化,dataframe,apache-spark,Dataframe,Apache Spark,使用spark shell测试功能 def smallDfToCSV(fname:String,df:org.apache.spark.sql.DataFrame):单位={ 导入java.io_ val pw=新的PrintWriter(新文件(fname)) val header=df.head.schema.map(r=>r.name) write(header.mkString(“,”+“\n”)//很好 df.limit(5000).foreach(r=>pw.write(r.mkSt
def smallDfToCSV(fname:String,df:org.apache.spark.sql.DataFrame):单位={
导入java.io_
val pw=新的PrintWriter(新文件(fname))
val header=df.head.schema.map(r=>r.name)
write(header.mkString(“,”+“\n”)//很好
df.limit(5000).foreach(r=>pw.write(r.mkString(“,”+“\n”))//错误!
//org.apache.spark.SparkException:任务不可序列化
关闭
}//\csvWr
val df=spark.sql(查询)
smallDfToCSV(“./lixo.csv”,df)
错误没有意义,因为它正在运行:
df.foreach(r=>println(r.mkString(“,”))
无法序列化该任务,因为PrintWriter
未实现java.io.Serializable
。在Spark执行器上调用的任何类(即映射
、减少
、foreach
,等等。数据集或RDD上的操作)都需要序列化,以便可以分发给执行器
我也很好奇您的功能的预期目标。由于此函数将在您的执行器上执行,因此您将获得写入
lixo.csv
的df
的部分内容,无论当前的工作目录是针对您的各个执行器的。如果您打算将df
的全部内容写入本地计算机上的文件,则必须首先通过collect
将其从RDD中取出,因为PrintWriter
未实现java.io.Serializable
,因此无法序列化该任务。在Spark执行器上调用的任何类(即映射
、减少
、foreach
,等等。数据集或RDD上的操作)都需要序列化,以便可以分发给执行器
我也很好奇您的功能的预期目标。由于此函数将在您的执行器上执行,因此您将获得写入
lixo.csv
的df
的部分内容,无论当前的工作目录是针对您的各个执行器的。如果您打算将df
的全部内容写入本地计算机上的文件,则必须首先通过collect
将其从RDD中取出。谢谢Charlie,您是对的(很好的解释!),“首先将其从RDD中取出”。因此,小型数据集的另一个解决方案(正如我现在使用limit
编辑的示例)是使用take(n)
方法,比如df.take(5000).foreach(r=>pw.write(r))
。关于您的好奇,函数smallDfToCSV()
是我真实世界函数的简化。。。。设想一个转储小数据集的调试。很高兴提供帮助!如果您想避免take()
、collect()
或sample
,我已经成功地使用了日志框架(如logback)将调试信息写入Spark的执行器日志,然后可以通过Spark web UI读取这些日志。这是如何通过log4j实现的一个很好的概述:谢谢Charlie,你是对的(很好的解释!),“首先从RDD中去掉它”。因此,小型数据集的另一个解决方案(正如我现在使用limit
编辑的示例)是使用take(n)
方法,比如df.take(5000).foreach(r=>pw.write(r))
。关于您的好奇,函数smallDfToCSV()
是我真实世界函数的简化。。。。设想一个转储小数据集的调试。很高兴提供帮助!如果您想避免take()
、collect()
或sample
,我已经成功地使用了日志框架(如logback)将调试信息写入Spark的执行器日志,然后可以通过Spark web UI读取这些日志。这是如何通过log4j实现的一个很好的概述: