鉴于
val as: RDD[(T, U)]
val bs: RDD[T]
我想过滤as
以查找包含密钥bs
的元素。
一种方法是
val intermediateAndOtherwiseUnnessaryPair = bs.map(b => b -> b)
bs.join(as).values
但bs
上的映射是不幸的。有更直接的方法吗?
答案 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
。