SPARK:使用“不可序列化”对象

时间:2015-10-21 16:36:05

标签: scala serialization apache-spark

我正在Spark中读取一个大型CSV文件,我想使用CSVParser库解析每一行(au.com.bytecode.opencsv.CSVParser)

这是我的代码:

val parsedLines = sc.textFile("path/to/a/csv/file.csv").map(line => {
     val parser = new CSVParser(',')
     try{
       parser.parseLine(line)
     }catch{
       case e: Exception => "Error"
     }
})

调用parser.parseLine(line)的结果是Array[String]

我无法在地图外创建解析器,因为CSVParser类不可序列化。

在地图函数中调用new CSVParser(',')是否可以像在上面的代码中那样调用?...如果是,为什么?...如果不是,为什么?

是否为RDD的每个元素调用new CSVParser(',')

有没有更有效的方法以不同的方式进行相同的处理?

2 个答案:

答案 0 :(得分:4)

就个人而言,我只是使用Databricks的spark-csv软件包来解析CSV文件,但如果你坚持使用CSVParser,则应该mapPartitions而不是{{1} }}。当您使用map时,确实为RDD中的每个元素调用了map,而如果您使用new CSVParser(),则每个分区只调用一次。

答案 1 :(得分:0)

var parser = new CSVParser(',');

你可以定义一个如下的函数并调用..

 private def getTokens(value: String): Array[String] = {
    if (!"".equals(value)) {
      var tokens: Array[String] = parser.parseLine(value);
        return tokens;
    }
    return null;
}