PySpark

时间:2017-04-09 01:01:49

标签: apache-spark pyspark

以下是代码: 代码行为是生成从0n的数字幂集。

C - 表示由所有大小l

组成的RDD

迭代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可以执行一些优化。

Issue1

1 个答案:

答案 0 :(得分:0)

Spark RDD是惰性的,除非进行缓存和/或检查点,否则每次访问RDD时都会评估它们的完整谱系。

因为您没有缓存而C取决于之前的Cs,Spark会评估C_i一次:

  • 适用于C_i.count()
  • 适用于C_i+1.count()

因为你partition Spark可以重用shuffle文件,否则它会一直递归回到第一个RDD。