Spark MapReduce中出现意外结果

Bo *_*kin 4 scala mapreduce apache-spark

我是Spark的新手,想要了解MapReduce是如何在幕后完成的,以确保我正确使用它.这篇文章提供了一个很好的答案,但我的结果似乎没有遵循所描述的逻辑.我在命令行上运行Scala中的Spark快速入门指南.当我正确地添加线长时,事情就好了.总线长度为1213:

scala> val textFile = sc.textFile("README.md")

scala> val linesWithSpark = textFile.filter(line => line.contains("Spark"))

scala> val linesWithSparkLengths = linesWithSpark.map(s => s.length)

scala> linesWithSparkLengths.foreach(println)

Result:
14
78
73
42
68
17
62
45
76
64
54
74
84
29
136
77
77
73
70

scala> val totalLWSparkLength = linesWithSparkLengths.reduce((a,b) => a+b)
    totalLWSparkLength: Int = 1213
Run Code Online (Sandbox Code Playgroud)

当我略微调整它以使用(ab)而不是(a + b)时,

scala> val totalLWSparkTest = linesWithSparkLengths.reduce((a,b) => a-b)
Run Code Online (Sandbox Code Playgroud)

根据这篇文章中的逻辑,我期望-1185 :

List(14,78,73,42,68,17,62,45,76,64,54,74,84,29,136,77,77,73,70).reduce( (x,y) => x - y )
  Step 1 : op( 14, 78 ) will be the first evaluation. 
     x is 14 and y is 78. Result of x - y = -64.
  Step 2:  op( op( 14, 78 ), 73 )
     x is op(14,78) = -64 and y = 73. Result of x - y = -137
  Step 3:  op( op( op( 14, 78 ), 73 ), 42) 
     x is op( op( 14, 78 ), 73 ) = -137 and y is 42. Result is -179.
  ...
  Step 18:  op( (... ), 73), 70) will be the final evaluation.
     x is -1115 and y is 70. Result of x - y is -1185.
Run Code Online (Sandbox Code Playgroud)

但是,发生了一些奇怪的事

scala> val totalLWSparkTest = linesWithSparkLengths.reduce((a,b) => a-b)
totalLWSparkTest: Int = 151
Run Code Online (Sandbox Code Playgroud)

当我再次运行时......

scala> val totalLWSparkTest = linesWithSparkLengths.reduce((a,b) => a-b)
totalLWSparkTest: Int = -151
Run Code Online (Sandbox Code Playgroud)

谁能告诉我为什么结果是151(或-151)而不是-1185?

zer*_*323 7

这是因为减法既不是关联的也不是可交换的.让我们从关联性开始:

(- (- (- 14 78) 73) 42) 
(- (- -64 73) 42)
(- -137 42) 
-179
Run Code Online (Sandbox Code Playgroud)

是不一样的

(- (- 14 78) (- 73 42))
(- -64 (- 73 42))
(- -64 31)
-95
Run Code Online (Sandbox Code Playgroud)

现在是交换时间:

(- (- (- 14 78) 73) 42) ;; From the previous example
Run Code Online (Sandbox Code Playgroud)

是不一样的

(- (- (- 42 73) 78) 14)
(- (- -31 78) 14)
(- -109 14)
-123
Run Code Online (Sandbox Code Playgroud)

Spark首先应用于reduce各个分区,然后以任意顺序合并部分结果.如果您使用的功能不符合一个或两个标准,则最终结果可能是非确定性的.