并行使用Scala Spark重命名HDFS文件时出现序列化问题

时间:2018-10-05 15:26:07

标签: scala apache-spark

我想使用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)

1 个答案:

答案 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