Spark广播vs加入

时间:2015-12-28 19:39:42

标签: python apache-spark distributed-computing

我有一个大的RDD(rdd_1)和一个过滤的子集(rdd_2)。我想在不同的领域加入rdd_1和rdd_2。

假设记录的格式为{'first_name':<>,'last_name':<>}。我们希望找到与所有'jack'具有相同姓氏的所有名称。

names = sc.textfile(RAW_DATA)
jack = names.filter(lambda v: v['first_name'] == 'jack')

选项1

jack_last_names = jack.map(operator.itergetter('last_name').distinct().collect()
last_names_bc = sc.broadcast(set(jack_last_names))
final = names.filter(lambda v:v['last_name'] in last_names_bc.value)

目前,我播放rdd_2并过滤rdd_1。麻烦的是,为了广播rdd_2,我必须首先在驱动程序上收集它()它会导致驱动程序内存不足。

有没有办法广播RDD而不先在驱动程序上收集()?

选项2

final = jack.keyBy(operator.itemgetter('last_name').join(names.keyBy(operator.itemgetter('last_name')

我的另一个选择是rdd_1.join(rdd_2),但是rdd_1太大而无法改组。

当我们运行rdd_1.join(rdd_2)时,rdd_1和rdd_2都会进行散列分区和洗牌吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

  

有没有办法广播RDD而不先在驱动程序上收集()?

不,没有,即使它不能解决你的问题。

  • 无法执行嵌套操作或转换
  • 如果您可以在没有收藏的情况下创建本地广播变量,那么您将遇到同样的问题但是在工作者身上
  

当我们运行rdd_1.join(rdd_2)时,rdd_1和rdd_2都会进行散列分区和洗牌吗?

从技术上讲,在PySpark中需要union后跟groupByKey,这意味着所有数据都必须进行洗牌。

在实践中,我只会接受改变行动的成本。通常,不可能编写任何复杂的应用程序并完全避免改组。此外,它并不比broadcasting a similar amount of data更昂贵,甚至可以将数据复制到具有复制功能的分布式文件系统。