查找RDD [T]中具有键的RDD [(T,U)]元素

时间:2016-03-18 04:28:01

标签: scala apache-spark

鉴于

val as: RDD[(T, U)]
val bs: RDD[T]

我想过滤as以查找包含密钥bs的元素。

一种方法是

val intermediateAndOtherwiseUnnessaryPair = bs.map(b => b -> b)
bs.join(as).values

bs上的映射是不幸的。有更直接的方法吗?

2 个答案:

答案 0 :(得分:2)

您可以通过执行以下操作来减少映射:

val intermediateAndOtherwiseUnnessaryPair = bs.map(b => (b, 1))

此外,加入前的共同分区有很大帮助:

val intermediateAndOtherwiseUnnessaryPair = bs.map(b => (b, 1)).paritionBy(new HashPartitioner(NUM_PARTITIONS))

bs.paritionBy(new HashPartitioner(NUM_PARTITIONS)).join(as).values

Co分区的RDD在运行时不会被洗牌,因此您可以看到显着的性能提升。

如果bs太大(更确切地说,具有大量唯一值),广播可能无效,您可能还想增加driver.maxResultsize

答案 1 :(得分:1)

使用第二个RDD过滤一个RDD的流行和一般方法是仅有两个(或至少是我所知道的唯一方法):

1)你已经在做的join - 在这种情况下我不会担心不必要的中间RDD那么多,map()是一个狭窄的转变而不会引入那么多开销。 join()本身很可能会很慢,因为它是一个广泛的转变(需要改组)

2)在驱动程序上收集bs并将其作为广播变量,然后将在as.filter()中使用

val collected = sc.broadcast(bs.collect().toSet)
as.filter(el => collected.value.contains(el))

您需要这样做,因为Spark不支持在RDDs上调用的方法中嵌套RDD