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

Apache spark 通过迭代另一个大RDD来过滤一个大RDD-pySpark,apache-spark,pyspark,rdd,Apache Spark,Pyspark,Rdd,我有一个很大的RDD,称之为RDD1,在初始过滤器之后大约有3亿行。我想做的是从RDD1中获取ID,并在另一个大型数据集中找到它的所有其他实例,称之为RDD2,即大约30亿行。RDD2是通过查询存储在Hive中的拼花地板表以及RDD1创建的。RDD1中的唯一ID数量约为1000万个元素 我的方法是当前收集ID并广播它们,然后过滤RDD2 我的问题是——有没有更有效的方法?还是这是最佳实践 我有以下代码- hiveContext = HiveContext(sc) RDD1 = hiveConte

我有一个很大的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))

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

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

我要做的是从RDD1中获取3亿个ID,构造一个bloom过滤器(),使用它作为广播变量来过滤RDD2,您将得到RDD2Partial,它包含RDD1中键的所有键值配对,以及一些误报。如果您期望结果在数百万的范围内,那么您将能够在RDD1和RDD2Partial上使用正常操作,如join、cogroup等,以获得准确的结果,而不会出现任何问题

这样,如果您希望结果的大小合理,那么就可以大大减少联接操作的时间,因为复杂性保持不变。您可能会得到一些合理的加速(例如2-10倍),即使结果在数亿以内

编辑


bloom筛选器可以有效地收集,因为您可以将一个元素设置的位与另一个元素设置的位与
组合在一起,这是关联的和可交换的。

为什么您要从表1中选择所有行,而只将它们与
RDD1.map()操作一起丢弃?那不是很有效率。这两个
id=
语句令人困惑。为什么要将它收集到前端,然后作为广播变量发送出去?您是否在没有
collect()
sc.broadcast
的情况下尝试过它?@vy32-我在以后的计算中使用了RDD1中的列-但我需要它的ID来查询第二个表。对于集合,您无法广播RDD,您会得到一个很好的异常。异常:似乎您正试图广播RDD或从操作或转换引用RDD。RDD转换和操作只能由驱动程序调用,不能在其他转换内部调用;见SPARK-5063。谢谢你,我真的很喜欢这个解决方案!这可能是一个noob问题,但bitarray是否比python中的集合使用更少的内存?