将文件名哈希附加到Spark RDD的每一行

时间:2015-09-29 04:09:20

标签: scala apache-spark

我正在尝试将文件目录加载到Spark RDD中,我需要为每一行附加原始文件名。

我无法使用sc.textFile找到使用常规RDD执行此操作的方法,因此我现在尝试使用WholeTextFiles方法以文件名加载每个文件。

我正在使用此代码:

val lines = 
     sc.wholeTextFiles(logDir).flatMap{ case (filename, content) =>
         val hash = modFiles.md5(filename)
         content.split("\n")
         .filter(line =>
            <filter conditions>
         .map(line => line+hash)
     }

但是这段代码给了我一个Java堆内存错误,我想它是试图一次加载所有文件?

有没有一种方法可以通过不使用wholeTextFiles来解决这个问题和/或有没有一种方法不使用wholeTextFiles一次加载所有文件?

1 个答案:

答案 0 :(得分:1)

解决方案是在此页面上应用代码:http://themodernlife.github.io/scala/spark/hadoop/hdfs/2014/09/28/spark-input-filename/

import org.apache.hadoop.io.LongWritable
import org.apache.hadoop.io.Text
import org.apache.hadoop.mapred.{FileSplit, TextInputFormat}
import org.apache.spark.rdd.HadoopRDD

  // Create the text file
  val text = sc.hadoopFile(logDir,
    classOf[TextInputFormat], classOf[LongWritable], classOf[Text], sc.defaultMinPartitions)

  // Cast to a HadoopRDD
  val hadoopRdd = text.asInstanceOf[HadoopRDD[LongWritable, Text]]
  val linesRaw = hadoopRdd.mapPartitionsWithInputSplit { (inputSplit, iterator) ⇒
    // get file name hash - you need to define your own hash function
    val fileHash = hash(inputSplit.asInstanceOf[FileSplit].getPath.toString)
    // input split is in _1 and line is in _2
    iterator.map(splitAndLine => splitAndLine._2+fileHash)
  }

与使用sc.textFile相比,使用此代码的性能下降了约10%