scala spark读取大文件csv太慢以及优化方案。

最近的业务场景中,spark要读取 1个30G的 csv文件,生成RDD后做运算,光这一个 parse 就用了1个半小时,太慢了,后来请大佬帮我优化,我们统计时间发现 ,spark 读取这个csv 竟然用了 30分钟,太慢了。而且后面跑运算的时候,一直是4个分区在跑,我们推测读取文件的时候 partition 少了。

关于spark 优化,网上有很多,我这里只把我这次的优化记录下来 ,希望能帮助新人。

老的读取csv,生成RDD的代码如下(这一部分读取文件生成RDD就用了30分钟):

val csvData = sparkSession.sqlContext.read.option("header",true).option("multiLine","true").option("quote","\"").option("escape","\"").csv(path)

val csvRDD = csvData.read.RDD.map(line=>{
    val person = new Person
    setValue(person,line)
})

1 简单快速优化方案,我们查看 hadoop running application,发现这个parse 最多只有500个分区,以及3个running containers在跑。我们分析,这种方式读取csv,估计是1个文件 1个分区。所以可以如下优化:

这种方案整个parse从1个小时降到了30分钟。

val csvData = sparkSession.sqlContext.read.option("header",true).option("multiLine","true").option("quote","\"").option("escape","\"").csv(path)

val csvRDD = csvData.read.RDD.repartition(500).map(line=>{
    val person = new Person
    setValue(person,line)
})

2 终极方案:

这种优化方案,整个parse 从1个小时优化到了20分钟。

val csvData = sparkSession.sqlContext.read.option("header",true).option("multiLine","true").option("quote","\"").option("escape","\"").csv(path)
val schema=csvData.schema
val headerFilter = schema.toList(0).name

sparkSession.sparkContext.textFile(path,500).repartition(500).filter(!_.contains(headerFilter)).filter(line=>checkCSVLine(line,schema)).map(line=>{
    val person = new Person
    setValue(person,line)
})
def checkCSVLine(line:String,schema:StrucType):Boolean={
    val csv = new CSVReader(new StringReader(line))
    val row = csv.readNex()
    if(row!=null && row.length == schema.length) true
    else false
}

PS: 在读取文件重分区之后,后面的运算就不用重分区了,因为 读取文件重分区后,运算中的重分区会根据你读取的文件个数成倍数增长。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值