Spark reduceByKey接收自己的输出作为后续调用的输入

时间:2014-07-22 14:50:12

标签: python apache-spark

我正在编写一个PySpark应用程序,用于计算笛卡尔空间中n维点之间的成对距离。我有一个flatMap步骤,它读取单个点并计算各种"块"在这个点的成对相似性矩阵中(我认为这是一种比天真的O(n ^ 2)计算更有效的方法;如果你有点好奇,请参阅Section 5.2 in this paper我的灵感)

包含数据点的文本文件具有以下格式:

x1_1,x1_2,x1_3,...,x1_n
x2_1,x2_2,x2_3,...,x2_n
...
xm_1,xm_2,xm_3,...,xm_n

这是我的司机:

rawdata = np.loadtxt(args['input'], dtype = np.str, delimiter = "\n")
indexed = np.vstack([np.arange(rawdata.shape[0]), rawdata]).T
D = sc.parallelize(indexed)

# Broadcast variables.
BLOCKING_FACTOR = sc.broadcast(sc.defaultParallelism)
SIZE = sc.broadcast(rawdata.shape[0])

retval = D.flatMap(parse_line).reduceByKey(pairwise_blocks).collect()

它将整个文本文件读入内存,然后为每一行编制索引,最后通过flatMap运行索引数据。这是parse_line方法:

def parse_line(line):
    index, data = line
    index = int(index)

    v = SIZE.value
    h = BLOCKING_FACTOR.value

    edgelength = int(numpy.ceil(v / h))

    J = int(index / edgelength)
    rows = [((((I + 1) * I) / 2) + J, [0, index, data]) for I in range(0, J)]

    I = int(index / edgelength)
    cols = [((((I + 1) * I) / 2) + J, [1, index, data]) for J in range(I, h)]

    return rows + cols

(k,v)对采用每个键是整数的形式 - 最终n-by-n成对相似矩阵中的唯一块 - 该值是由两个整数组成的3元素列表和一个字符串。

问题在于:当reduceByKey调用pairwise_blocks方法时,早期迭代的输出作为后续调用的输入反馈。即:

def pairwise_blocks(x1, x2):
    print x1 # for debugging; see below comments
    x = np.array(map(float, x1[2].split(",")))
    y = np.array(map(float, x2[2].split(",")))
    return [-1, la.norm(x - y)]

前几次调用按预期返回[-1, dist],但很快就得到以下异常(前两行是上述方法中调试输出的结果):

[1, 1, '-8.366703221982483285e+00,-3.082631504065840300e+00']
[-1, 6.4988099869742415]
PySpark worker failed with exception:
Traceback (most recent call last):
    File "/home/Spark/spark-1.0.1-bin-hadoop2/python/pyspark/worker.py", line 77, in main
        serializer.dump_stream(func(split_index, iterator), outfile)
    File "/home/Spark/spark-1.0.1-bin-hadoop2/python/pyspark/rdd.py", line 283, in func
        def func(s, iterator): return f(iterator)
    File "/home/Spark/spark-1.0.1-bin-hadoop2/python/pyspark/rdd.py", line 1134, in _mergeCombiners
        combiners[k] = mergeCombiners(combiners[k], v)
    File "/home/Programming/PySpark-Affinities/cartesian.py", line 60, in pairwise_blocks
        x = np.array(map(float, x1[2].split(",")))
    IndexError: list index out of range

最近打印的调试输出格式为[-1, dist]知道为什么会这样吗?我是否错过了某处的配置步骤或指定此行为的文档?我不是map-reduce向导,但我已经足够使用它以至于之前没有考虑过这种行为,特别是我使用reduceByKey

编辑:作为推论并帮助调试,reduceByKey步骤中是否有任何方法可以访问当前呼叫正在减少的密钥?

非常感谢!

1 个答案:

答案 0 :(得分:0)

我谦卑地说,这个问题揭示了我还在学习Spark多少;这确实是减速器展现的正确行为。我仍然没有学习我的一些Hadoop体验,其中Hadoop Reducers在Spark中有效地作为groupByKey后跟reduceByKey的一两个组合步骤。我最卑鄙的道歉。