[英]Spark: Fastest way to look up an element in an RDD
我有一個自定義的E類,其中除其他外還有一個領域word
。 我有一個大的es: RDD[E]
帶有幾個100000元素的es: RDD[E]
和一個doc: Seq[String]
通常有幾百個條目的doc: Seq[String]
。 在es
,每個元素的word
字段值都是唯一的。
我的任務是為doc
每個字符串查找es
的元素。 但是,不能保證存在這樣的元素。 因此,我朴素的Scala / Spark實現是:
def word2E(words: Seq[String]): Seq[E] = {
words.map(lookupWord(_, es))
.filter(_.isDefined)
.map(_.get)
}
方法lookupWord()
定義如下:
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階段概述時, lookupWord()
似乎是一個瓶頸。 特別是在某些情況下, lookupWord
的isEmpty()
調用lookupWord
花費相對較長的時間(最多2s)。
我已經堅持了es
RDD。 是否還有其他方法可以優化此類任務,或者與在此類數據集上進行操作時獲得的效果一樣好嗎?
我注意到PairRDDFunctions
的lookup()
方法,並考慮構造一個PairRDD,其中word
字段將用作鍵。 可能有幫助嗎? 通過實驗得出任何結論都非常困難,因為涉及的因素太多。
您的實現的問題是,你觸發每個字words
你的完整遍歷RDD
,然后收集要素。 解決問題的一種方法是將單詞序列與RDD
:
case class E(word: String, value: Int)
object App {
def main(args: Array[String]) {
val sparkConf = new SparkConf().setAppName("Test").setMaster("local[4]")
val sc = new SparkContext(sparkConf)
val entries = sc.parallelize(List(E("a", 1), E("b", 2), E("c", 3), E("c", 3)))
val words = Seq("a", "a", "c")
val wordsRDD = sc.parallelize(words).map(x => (x, x))
val matchingEntries = entries
.map(x => (x.word, x))
.join(wordsRDD)
.map{
case (_, (entry, _)) => entry
}
.collect
println(matchingEntries.mkString("\n"))
}
}
輸出是
E(a,1)
E(a,1)
E(c,3)
E(c,3)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.