通过迭代另一个大型RDD来过滤大型RDD - pySpark

时间:2016-01-22 04:57:13

标签: apache-spark pyspark rdd

我有一个大的RDD,称之为RDD1,在初始过滤器之后大约有3亿行。我想做的是从RDD1获取ID并在另一个大型数据集中查找它的所有其他实例,称之为RDD2,即大约30亿行。 RDD2是通过查询存储在Hive和RDD1中的镶木桌来创建的。 RDD1中唯一ID的数量约为1000万个元素。

我的方法是当前收集ID并广播它们然后过滤RDD2。

我的问题是 - 有更有效的方法吗?或者这是最佳做法?

我有以下代码 -

hiveContext = HiveContext(sc)
RDD1 = hiveContext("select * from table_1")
RDD2 = hiveContext.sql("select * from table_2")

ids = RDD1.map(lambda x: x[0]).distinct() # This is approximately 10 million ids
ids = sc.broadcast(set(ids.collect()))

RDD2_filter = RDD2.rdd.filter(lambda x: x[0] in ids.value))

2 个答案:

答案 0 :(得分:2)

我认为最好只使用一个SQL语句来进行连接:

RDD2_filter = hiveContext.sql("""select distinct t2.*
                                 from table_1 t1
                                 join table_2 t2 on t1.id = t2.id""")

答案 1 :(得分:1)

我要做的是从RDD1获取300 mil的id,构建一个bloom过滤器(Bloom filter),使用它作为广播变量来过滤RDD2,你将获得包含key的所有键值parits的RDD2Partial在RDD1中,加上一些误报。如果您希望结果在数百万的数量级之内,那么您将能够在RDD1和RDD2Partial上使用正常操作(如join,cogroup等)来获得准确的结果而没有任何问题。

这样,如果您希望结果具有合理的大小,则可以大大减少连接操作的时间,因为复杂性保持不变。即使结果在数亿的数量级内,您也可能获得一些合理的加速(例如2-10x)。

修改

可以有效地收集布隆过滤器,因为您可以将由一个元素设置的位与由OR设置的另一个元素设置的位组合,这是关联和可交换的。