我有一个大的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))
答案 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
设置的另一个元素设置的位组合,这是关联和可交换的。