我在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
答案 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
。