我有一个RDD final_rdd ,我正在使用累加器在驱动程序上收集它并转换为List。
val acumFileKeys = sc.collectionAccumulator[String]("File Keys")
var input_map_keys = ListBuffer(input_map.keys.toSeq: _*)
final_rdd.keys.foreach(m => acumFileKeys.add(m.trim))
import collection.JavaConverters._
acumFileKeys.value.asScala.toList.foreach(fileKey => { // code goes here })
foreach循环在驱动程序上运行,并且仅使用5个内核中的1个内核。进而导致性能降低。有什么办法可以利用驱动程序的所有核心。 以下是spark-submit命令。我们共有5个工作人员,每个工作人员有5个核心,每个核心都有16G内存。
spark-submit --class com.test.MyMainClass \
--deploy-mode cluster \
--master spark://master_ip:7077 \
--executor-cores 5 \
--conf spark.driver.maxResultSize=5G \
--conf spark.network.timeout=800s \
--executor-memory 8g \
--driver-memory 8g \
/opt/jars/my_app.jar
答案 0 :(得分:0)
使用Scala并行集合-https://docs.scala-lang.org/overviews/parallel-collections/configuration.html
val list = acumFileKeys.value.asScala.toList
import scala.collection.parallel._
val forkJoinPool = new scala.concurrent.forkjoin.ForkJoinPool(5)
val parallelList = list.par
parallelList.tasksupport = new ForkJoinTaskSupport(forkJoinPool)
parallelList.foreach { case fileKey =>
println(Thread.currentThread.getName)
...
}
答案 1 :(得分:0)
首先,final_rdd.keys.foreach
不是for循环。在这种情况下,foreach
是对rdd
的一项操作,它是远程执行的。已经并行化了。
通常,利用驱动程序的计算资源没有太多意义。在典型的工作流程中,驱动程序大部分负载不足,并且只能协调工作人员上发生的计算。
在您的特定情况下,代码可以重写为final_rdd.keys.collect()
。