Performance Spark:在RDD中查找元素的最快方法

Performance Spark:在RDD中查找元素的最快方法,performance,scala,apache-spark,Performance,Scala,Apache Spark,我有一个自定义类E,其中包括一个字段word。我有一个大的es:RDD[E],有100000个元素,还有一个doc:Seq[String]通常有几百个条目。在es中,每个元素的word字段值都是唯一的 我的任务是在es中查找doc中每个字符串的元素。但是,不能保证存在这样的元素。因此,我天真的Scala/Spark实现是: def word2E(words: Seq[String]): Seq[E] = { words.map(lookupWord(_, es)) .filter(_

我有一个自定义类E,其中包括一个字段
word
。我有一个大的
es:RDD[E]
,有100000个元素,还有一个
doc:Seq[String]
通常有几百个条目。在
es
中,每个元素的
word
字段值都是唯一的

我的任务是在
es
中查找
doc
中每个字符串的元素。但是,不能保证存在这样的元素。因此,我天真的Scala/Spark实现是:

def word2E(words: Seq[String]): Seq[E] = {
  words.map(lookupWord(_, es))
    .filter(_.isDefined)
    .map(_.get)
}
方法
lookupford()
定义如下:

def lookupWord(w: String, es: RDD[E]): Option[E] = {
  val lookup = es.filter(_.word.equals(w))

  if (lookup.isEmpty) None
  else Some(lookup.first)
}
当我查看Spark stages概述时,似乎
lookupford()
是一个瓶颈。特别是,在某些情况下,
lookupord
中的
isEmpty()
调用需要相对较长的时间(最多2秒)

我已经保存了
es
RDD。优化这样的任务是否还有其他杠杆作用,或者这是否与在这样的数据集上操作时得到的一样好

我注意到
pairddfunctions
中的
lookup()
方法,并考虑构造一个pairdd,其中
word
字段将作为键。那会有帮助吗?
在这里通过实验得出任何结论都是相当困难的,因为涉及到太多的因素。

实现的问题是,您触发了
单词中每个单词的
RDD的完整遍历,然后收集元素。解决问题的一种方法是将单词序列与
RDD

案例类别E(字:字符串,值:Int)
对象应用程序{
def main(参数:数组[字符串]){
val sparkConf=new sparkConf().setAppName(“测试”).setMaster(“本地[4]”)
val sc=新的SparkContext(sparkConf)
val entries=sc.parallelize(列表(E(“a”,1),E(“b”,2),E(“c”,3),E(“c”,3)))
val词语=顺序(“a”、“a”、“c”)
val wordsRDD=sc.parallelize(words).map(x=>(x,x))
val matchingEntries=条目
.map(x=>(x.word,x))
.join(wordsRDD)
.地图{
案例(,(条目,))=>条目
}
.收集
println(matchingEntries.mkString(“\n”))
}
}
输出是

E(a,1)
E(a,1)
E(c,3)
E(c,3)

您可以尝试一个索引RDD—请参阅此处接受的答案:IndexedRDDD看起来确实像是在解决我的确切任务。然而,它们在最新的Spark发行版(截至编写时为1.4.1)中还不可用。这看起来很有希望,尽管我需要在输入字符串和
E
元素之间建立映射;虽然不是直接映射,但如果
doc
中包含两个等于字符串,则匹配的
E
应该在结果序列中出现两次;我想,通过模拟多重映射,这可能是可行的。@Carsten,我是否正确地理解了您的意思,您实际上在寻找一个联接操作?因此,如果
words=Seq(“a”、“a”、“c”)
您想要输出
Seq(E(“a”),1,E(“a”,1),E(“c”,3),E(“c”),E(“c”),3”)
?@Carsten,我已经用一个连接解决方案更新了我的答案。这个答案确实起到了作用,现在的性能肯定要快得多。我还尝试了我最初简要描述的解决方案,创建了一个
pairdd
,并使用了它的
lookup()
方法:也比使用
join()
要快得多,但速度要慢得多(尽管进行客观比较仍然相当困难)。您也可以尝试使用广播联接,因为
单词
序列非常小。看这里