减少跨越分区的火花功能pyspark

时间:2017-07-20 12:16:35

标签: python apache-spark pyspark

我在python中使用spark编写了一个示例函数。功能如下

#!/usr/bin/env python
from __future__ import print_function
from pyspark.sql import SparkSession
import os
import sys
os.environ["SPARK_HOME"] = "/usr/local/spark"
os.environ["PYSPARK_PYTHON"]="/usr/bin/python3.4"

spark = SparkSession \
    .builder \
    .appName("testpython") \
    .getOrCreate()
rdd1 = spark.sparkContext.parallelize([1,6,5,2,99,1000,100009,10000,139,44,45343,23234,34])
**rdd3=rdd1.reduce(lambda x,y:x+1)**
print(rdd3)

在我们给出的reduce函数(lambda x,y:x + 1)中,上述函数的理想结果必须为13,但结果为6

任何人都可以解释为什么结果是6而不是13? 是因为在spark中分区数据的设想?

控制台输出:

/usr/bin/python3.4 /home/PycharmProjects/sampleproject/ttestexmple.py
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
17/07/20 17:45:14 WARN NativeCodeLoader: Unable to load native-hadoop 
17/07/20 17:45:14 WARN Utils: Set SPARK_LOCAL_IP if you need to bind to another address

6

处理完成,退出代码为0

2 个答案:

答案 0 :(得分:2)

是的,你是对的。您可以使用

确保您的rdd仅位于1个分区
rdd1 = rdd1.coalesce(1)
rdd2 = rdd1.reduce(lambda x,y: x+1)

现在你将得到预期的答案。

原因是当你的rdd有一个以上的分区并且你正试图使用​​一个完全不使用y的reduce。所以让我们说你的rdd有两个分区,所以你的reduce会得到这样的(reduce on partition 1, reduce on partition 2),最后它会给你reduce result on partion 1 + 1

答案 1 :(得分:0)

更具体地说,reduce期望(或更确切地说,是一个具有关联性和可交换性的二进制函数,即函数f(x, y) = x op y使得

x op (y op z) = (x op y) op z

x op y = y op x

在不满足这些要求的情况下,当合并来自不同分区的中间结果时,您将无法保证最终结果将是相同的。关联性确保计算可以完全并行化;可交换性确保并行计算可以简化为相同的最终结果(因为您不知道中间结果的最终组合顺序)。

您可以轻松地看到您的函数不满足任何一个条件,因此不能与reduce可靠地使用:

x op (y op z) = x op (y + 1) = x + 1

(x op y) op z = (x + 1) op z = x + 2

对于任何x值都不相等。同样,

x op y = x + 1

当且仅当x = y时等于y op x