我想使用spark并行重命名HDFS文件。但是我遇到了序列化异常,我在代码后提到了异常。 使用spark.sparkContext.parallelize时出现此问题。当循环执行时,我也能够重命名所有文件。
def renameHdfsToS3(spark : SparkSession, hdfsFolder :String, outputFileName:String,
renameFunction: (String,String) => String, bktOutput:String, folderOutput:String, kmsKey:String): Boolean = {
try {
val fs = FileSystem.get(spark.sparkContext.hadoopConfiguration)
val path = new Path(hdfsFolder)
val files = fs.listStatus(path)
.filter(fs => fs.isFile)
val parallelRename=spark.sparkContext.parallelize(files).map(
f=>{
parallelRenameHdfs(fs,outputFileName,renamePartFileWithTS,f)
}
)
val hdfsTopLevelPath=fs.getWorkingDirectory()+"/"+hdfsFolder
return true
} catch {
case NonFatal(e) => {
e.printStackTrace()
return false
}
}
}
以下是我得到的例外
org.apache.spark.SparkException: Task not serializable
at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:340)
Caused by: java.io.NotSerializableException: org.apache.hadoop.fs.LocalFileSystem
Serialization stack:
- object not serializable (class: org.apache.hadoop.fs.LocalFileSystem, value: org.apache.hadoop.fs.LocalFileSystem@1d96d872)
- field (class: at org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40)
答案 0 :(得分:1)
该方法不正确,因为sc.parallelize用于通过RDD消耗数据。您需要在操作系统级别上工作。存在许多这样的帖子。
这样的事情应该足以将其与您自己的逻辑混合在一起,注意par允许并行处理,例如:
originalpath.par.foreach( e => hdfs.rename(e,e.suffix("finish")))
您需要检查如何使用.par定义并行性。在这里https://docs.scala-lang.org/overviews/parallel-collections/configuration.html