Spark通过mapPartitions方式加载Json文件,提高文件加载速度

来源:互联网 发布:网络大电影审批 编辑:程序博客网 时间:2024/06/05 19:08

这几天遇到了需要从hdfs加载json字符串,然后转化成json对象的场景。刚开始的实现方式见如下代码:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. val loginLogRDD = sc.objectFile[String](loginFile, loadLoginFilePartitionNum)  
  2.      .filter(jsonString => {  
  3.      //val loginItem = line.toString().split("\t")  
  4.      //LoginRecord(loginItem(0).toInt, loginItem(1), loginItem(2), loginItem(3).toInt, loginItem(4), loginItem(5), loginItem(6), loginItem(7).toInt, loginItem(8), loginItem(9), loginItem(10), loginItem(11), loginItem(12))  
  5.      val json = JSON.parseFull(jsonString)  
  6.      val resultJson = json match {  
  7.        case Some(map: Map[String, Any])  => if (map.get("ip").getOrElse("").equals("")) false else true  
  8.        case None => false  
  9.      }  
  10.      resultJson  
  11.      }).  

从以上代码可知,每条Json记录,都会创建Json解析器来进行解析。

这种方式加载速度特别慢,1s大概才1M左右,并且CPU也特别忙。因此推测是Spark程序有问题导致的。

为了提高记载速度,决定采用mapPartitions方式加载Json串,也就是每个分区只创建一个Json解析器,代码如下:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. val loginLogRDD = sc.objectFile[String](loginFile, loadLoginFilePartitionNum)  
  2.       .mapPartitions(jsonStringIter=>{  
  3.       val mapper = new ObjectMapper()  
  4.       mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)  
  5.       mapper.registerModule(DefaultScalaModule)  
  6.       jsonStringIter.map(record => {  
  7.         try {  
  8.           Some(mapper.readValue(record, classOf[JsonLoginRecord]))  
  9.         } catch {  
  10.           case e: Exception => None  
  11.         }  
  12.   
  13.       })  
  14.     })  

修改之后,每秒加载速度达到了100多兆,速度提高了100多倍,效果截图如下:

0 0