我是Scala和Spark的新手。这是我整个代码的一个简单示例:
package trouble.something
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
object Stack {
def ExFunc2(looku: RDD[(Int, List[(Double, Int)])], ke: Int): Seq[List[(Double, Int)]] = {
val y: Seq[List[(Double, Int)]] = looku.lookup(ke)
val g = y.map{x =>
x
/* some functions here
.
.
*/
}
g
}
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[*]").setAppName("toy")
val sc = new SparkContext(conf)
val pi: RDD[(Int, List[(Double, Int)])] = sc.parallelize(Seq((1, List((9.0, 3), (7.0, 2))), (2, List((7.0, 1), (1.0, 3))), (3, List((1.0, 2), (9.0, 1)))))
val res = ExFunc2(pi, 1)
println(res)
}
}
我正在运行足够大的数据,我需要更快的性能。通过查看Spark的Web UI和软件分析器。消耗时间最长的是lookup()
函数:
val y: Seq[List[(Double, Int)]] = looku.lookup(ke)
在RDD而不是lookup()
函数中查找元素的替代方法和方法是什么?
有一个与此问题相关的讨论Spark: Fastest way to look up an element in an RDD。但是,它并没有给我任何想法。
答案 0 :(得分:3)
如果您仔细使用和缩放它,那么查找功能不会出现性能问题。
def lookup(key: K): Seq[V]
返回RDD中键值的列表。如果RDD通过仅搜索键映射到的分区而具有已知分区器,则此操作有效地完成。
默认情况下,生成PairRdd的函数使用HashPartitioner。因此,请检查您的spark.default.parallelism
值设置为什么,因为这是HashPartitioner will default to的分区数。您可以调整该参数以匹配您正在使用的# of executors * # of cores per executor
。
您应该确认您的PairRdd确实具有已知的分区程序,如果没有,请使用partitionBy
创建一个,或者在创建PairRdd时修改现有代码以使用HashPartitioner。
let parallelismFactor = # of executors * # of cores per executor
然后,如果查找功能仍然太慢,则需要增加您正在使用的parallelismFactor
。现在spark将知道要查找的分区,并且当您增加parallelismFactor
时,您将减小每个分区的大小,这将提高查找的速度。
请注意,您可能希望拥有多倍于executors * cores
的分区,您必须自己对用例进行基准测试,尝试的分区数比分区数增加1-10倍executors * cores
。< / p>