以下是代码:
代码行为是生成从0
到n
的数字幂集。
C
- 表示由所有大小l
迭代l
中的所有可能的大小l + 1
的超集都会为C
中的集枚举,并存储回C
。
根据标准消除了枚举中的一些集合,在此示例中通过随机生成器输出的条件进行演示。
from pyspark import SparkConf
from pyspark import SparkContext
from bitarray import bitarray
import random
def setadd(u, i):
r = u.copy()
r[i] = 1
return r
def stringToBit(u):
r = bitarray()
r.frombytes(u)
return r
def mapFunc(it):
global bdTH
global bdN
for s in it:
s = stringToBit(s[0])
print(s)
r = random.randint(1, 10)
# elimination criteria
if r < bdTH.value:
continue
xmax = n - 1
while not s[xmax]:
xmax -= 1
for x in xrange(xmax + 1, bdN.value):
if s[x]:
continue
ns = setadd(s, x)
yield (ns.tobytes(), 0)
def main(sc, n):
phi = bitarray('0') * n
C = [(setadd(phi, x).tobytes(), 0) for x in xrange(n)]
print(C)
C = sc.parallelize(C)
global bdN
bdN = sc.broadcast(n)
global bdTH
bdTH = sc.broadcast(random.randint(1, 10))
l = 1
while l <= n:
C = C.partitionBy(100)\
.mapPartitions(mapFunc)
l += 1
if C.count():
print('count: ' + str(C.count()))
else:
print('count: 0' )
bdTH = sc.broadcast(random.randint(1, 10))
if __name__ == "__main__":
conf = SparkConf()
conf = conf.setAppName("test")
sc = SparkContext(conf = conf)
n = 5
main(sc, n)
sc.stop()
问题:
1.因为代码确实要保证两次不评估任何子集。但是,输出确实表明某些集合被评估两次
2.仅在为迭代broadcast
生成bdTH
之后才保证变量C
的{{1}}发送,或者Spark可以执行一些优化。
答案 0 :(得分:0)
Spark RDD是惰性的,除非进行缓存和/或检查点,否则每次访问RDD时都会评估它们的完整谱系。
因为您没有缓存而C
取决于之前的Cs
,Spark会评估C_i
一次:
C_i.count()
C_i+1.count()
因为你partition
Spark可以重用shuffle文件,否则它会一直递归回到第一个RDD。