优化Spark操作(计数和收集)

时间:2015-06-30 00:51:08

标签: scala optimization apache-spark

我的spark代码中有两个操作占用了大量的计算时间 - 代码行是

val d = x.map{case(x1,(x2,x3))=>(x2,x3)}.distinct.count.toDouble

对大约3500万行数据大约需要1.5分钟。我也尝试过使用这个命令 -

val d = x.map{case(x1,(x2,x3))=>(x2,x3)}.distinct.countApprox(timeout = 30, confidence = 0.95).

这确实会在~24秒内返回正确的结果。结果是 -

res42: org.apache.spark.partial.PartialResult[org.apache.spark.partial.BoundedDouble] = (final: [8627.000, 8627.000])

这是正确的,但我不知道如何访问此计数以在我的计算中使用。

第二行代码是 -

var num = y.values.toArray

在~1.6分钟内返回 -

res46: Array[Double].

我用这个数组来计算 -

y.map{case(k,v)=>(k,(num.filter(_<=v).length.toDouble/num.length.toDouble*100))}.

有更有效的方法来进行这些计算吗?任何帮助将不胜感激!

更新 我已经找到了如何使用计数的近似结果 -

x.map{case(x1,(x2,x3))=>((x2,x3),1)}.distinct.countApprox(30,0.95).getFinalValue.high.toDouble

ADDED

var s = x.map{case(x1,(x2,x3))=>((x1,x2,x3),1)}.reduceByKey(_+_).map{case((x1,x2,x3),x4)=>((x2,x3),(x1,x4))}.
    join(x.map{case(x1,(x2,x3))=>((x2,x3),1)}.reduceByKey(_+_)).map{case((x2,x3),((x1,x4),x5))=>
    (x1,(x4.toDouble/x5.toDouble*x3.toDouble, x3.toDouble))}

    var f = s.mapValues(_._1).reduceByKey(_+_).join(s.mapValues(_._2).reduceByKey(_+_)).map{case(k,v)=>(k,v._1/v._2)}

    val d = x.map{case(x1,(x2,x3))=>((x2,x3),1)}.distinct.countApprox(30,0.95).getFinalValue.high.toDouble

    var varietyFrac = x.distinct.mapValues(_=>1).reduceByKey(_+_).map{case(x1,x2)=>(x1,x2.toDouble/d)}

    var y = f.join(varietyFrac).map{case(name,(frac,varietyFrac))=>(name,pow((frac.toDouble*varietyFrac.toDouble),0.01)/0.01)}.persist

0 个答案:

没有答案