繁体   English   中英

Spark作业中的累加器太多了

[英]Too many Accumulators in Spark Job

我的火花应用程序有40个累加器

object MySparkApp { 
  def main(args: Array[String]): Unit = {
    // initialize SparkContext

    val acc1 = sc.accumulator(0)
    val acc2 = sc.accumulator(0)
    .
    .
    val acc40 = sc.accumulator(0)

    val logRdd = sc.textFile("input/path").map(x => parser.parse(x))
    logRdd.forEach(x => incrementCounter(x, acc1, acc2,..... acc40))
  }
}

这段代码非常难看,将这些累加器包装在像对象之类的东西中,并使代码更具可读性。

一种选择是为Map[String, Long]类型实现累加器 - 然后添加一个条目,其中“bad”字段名称作为键,并且为数据中每次出现的错误值添加1作为值:

累加器参数的实现:

class StringToLongAccumulatorParam extends AccumulatorParam[Map[String, Long]] {
  override def addInPlace(r1: Map[String, Long], r2: Map[String, Long]): Map[String, Long] = {
    // merging the maps:
    r1 ++ r2.map{ case (k,v) => k -> (v + r1.getOrElse(k,0L)) }
  }

  override def zero(initialValue: Map[String, Long]): Map[String, Long] = Map[String, Long]()
}

然后,您可以通过使用此参数的实例创建隐式val ,然后创建并使用适当的累加器来使用它:

implicit val accParam = new StringToLongAccumulatorParam()
val accumulator = sc.accumulator[Map[String, Long]](Map[String, Long]())
val rdd2 = rdd.map(v => { accumulator += Map("FieldName" -> 1); v })

当然 - 将"FieldName"更改为您需要的任何内容。 对于每条记录,您可以根据需要创建包含任意数量条目的地图,然后使用+=将其添加到累加器中。

注意 :如果你有很多这些错误的值,我不确定它会表现如此之好 - 但是如果你的大多数记录都不会最终创建这些地图,那么它应该可以忽略不计。 如果大多数记录都有空/坏值,也许这应该通过累加器来完成,而是通过实际的RDD操作(映射到值为坏的1 s并减少?)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM