从scala中的映射rdd获取键值

从scala中的映射rdd获取键值,scala,apache-spark,hashmap,rdd,Scala,Apache Spark,Hashmap,Rdd,我有一个RDD,它的元素是地图。当然,我不能使用RDD.get。因此,到目前为止,我执行以下操作以从该映射中获取键的值: val x = RDD.collect().flatten.toMap 然后 x.get(key) 获取键的值。现在,有一个非常大的rdd,它输出错误java.lang.OutOfMemoryError:GC开销超出了我在rdd上应用.collect()时的限制。如果不在rdd上应用.collect(),我怎么做呢?由于您无法将所有内容都应用到驱动程序中,因此首先需要过滤

我有一个RDD,它的元素是地图。当然,我不能使用RDD.get。因此,到目前为止,我执行以下操作以从该映射中获取键的值:

val x = RDD.collect().flatten.toMap
然后

x.get(key)

获取键的值。现在,有一个非常大的rdd,它输出错误
java.lang.OutOfMemoryError:GC开销超出了我在rdd上应用.collect()时的限制。如果不在rdd上应用.collect(),我怎么做呢?

由于您无法将所有内容都应用到驱动程序中,因此首先需要过滤rdd以获得需要查看的地图,然后执行get

val rdd = sc.parallelize(List(Map("a"->1,"b"->2),Map("c"->3,"d"->4)))

val key = "d"

val filteredRDD = rdd.filter(_.keySet contains key)

if (!filteredRDD.isEmpty) filteredRDD.first.get(key) else None

如果它确实是
Map
s,则可以执行以下操作:

rdd.flatMap(identity).lookup(key)
虽然这仍然会输出到驱动程序,但只有来自该键的值。所以,如果你能把它记在记忆里,那你就很擅长了。但如果您仍想将其作为rdd使用,那么:

rdd.flatMap(identity)
   .flatMap{case (key, value) => if(key == myKey) Some(value) else None}

如果您需要键和值,那么您可以将
flatMap
转换为一个过滤器,只需在
key==myKey

上进行过滤。您可以分享一个包含预期输出的可复制示例吗?我突然想到的一件事是,您调用collect(一个“操作”)太早了。您需要将RDD转换成(希望是)更小的RDD——基本上您只需要那些具有所需键的元素——然后在RDD中只有几个元素的最后时刻调用collect。我不知道
查找
,这显然是在这里使用的正确功能。但是,您的第二个
flatMap
看起来很像一个
过滤器
…谢谢@CyrilleCorpet我修改了答案,以明确我选择flatMap的原因,但为了以防万一,给了过滤器一个标注。@JustinPihony,上述方法有效,但是我必须在另一个rdd中使用“rdd.flatMap(identity.lookup(key)”,比如rdd2。对于rdd2的每个元素,我必须在“rdd”中查找其值。引发的错误是,此RDD缺少SparkContext。它可能发生在以下情况:(1)驱动程序不调用RDD转换和操作,而是在其他转换内部调用;例如,rdd1.map(x=>rdd2.values.count()*x)无效,因为无法在rdd1.map转换内执行值转换和计数操作