2018/04/10
本来思路是,用布隆过滤器过滤重复的项,开始需要把这个布隆过滤器作为累加器在执行动作的时候添加进去。然后把这个布隆过滤器广播出去,发现重复的都可以直接扔掉。
类似于上个变量作用域的问题。
由于是分布式处理,所以必须把这个变量共享,可用的资源就是spark的累加器。
但是不知道是不是实现的问题,还是我没有把他的类写好,在设置了累加参数之后,仍然不好使。
失败代码:
19 from pyspark.accumulators import AccumulatorParam
20
21 #zero_value
22 class bf_accu(AccumulatorParam):
23
24 def __init__(self,value):
25 self.
26
27 @classmethod
28 def zero(self,value):
29 return value
30
31 def addInPlace(self,value1,value2):
32 self.value1.add(value2)
33 return value1
然后想着换一个思路,布隆过滤器也就是为了查重嘛,所有想着直接就当场查了,也就是回归最原始的方法。
结果。。。。
35 test_one = records.filter(lambda x: filter_payload.lookup(x.split("\t")[-1]) > 1)
返回错误是:
pickle.PicklingError: Could not serialize object: Exception: It appears that you are attempting to
broadcast an RDD or reference an RDD from an action or transformation.
RDD transformations and actions can only be invoked by the driver,
not inside of other transformations; for example, rdd1.map(lambda x: rdd2.values.count() * x)
is invalid because the values transformation and count action cannot be performed inside of
the rdd1.map transformation. For more information, see SPARK-5063.
意思就是说不能在转化过程中执行动作。(捂脸)
这就尴尬了。这也给以后写代码提了个醒。
现在看来就得换些方法了。
最后决定,用这个内置的rdd转化方法来完成。
一定要把这个rdd都转化成(key,value)的形式。
然后利用subtractByKey,这样就可以把这个,那种重复key的项给排除出来。(想要相反的一部分,完全可以对前面的取反)
另外,这个速度,就真的慢了,这个时候就真的需要优化了。。
http://tech.magnetic.com/2016/01/bloom-filter-assisted-joins-using-pyspark.html
这个是使用pybloom的一个范例,虽然看不太懂。
另外,好像是,python版本的没有内置在spark的bloomfilter,我看java和scala都有。
github上也fork了一个还在更新的bloom_filter.叫做bloomfilter_live。
后期可以看这个效率是不是就会变高。
2018/04/11
最后还是用了一堆基础命令,来实现了。
现在不能确定就慢,或者另外一种就快。
本身就不确定这个东西,就可以实现,或者说,适用于我的办法。