我稍后看到了以下帖子:Understanding TreeReduce in Spark
我仍在尝试准确理解何时使用treeReduce与reduceByKey。我想我们可以使用像字数一样的通用示例来帮助我进一步了解正在发生的事情。
编辑:所以玩spark-shell,我认为我从根本上不理解treeReduce的概念,但希望这个例子和那些问题有所帮助。
res2: Array[(String, Int)] = Array((D,1), (18964,1), (D,1), (1,1), ("",1), ("",1), ("",1), ("",1), ("",1), (1,1))
scala> val reduce = input.reduceByKey(_+_)
reduce: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[11] at reduceByKey at <console>:25
scala> val tree = input.treeReduce(_+_, 2)
<console>:25: error: type mismatch;
found : (String, Int)
required: String
val tree = input.treeReduce(_+_, 2)
答案 0 :(得分:6)
两者之间存在根本区别 - reduceByKey
仅适用于键值对RDD,而treeReduce
是对任何RDD的reduce
操作的推广。 reduceByKey
用于实现treeReduce
,但它们在任何其他意义上都不相关。
reduceByKey
执行每个密钥的减少,从而产生RDD;它不是RDD意义上的“动作”,而是一个返回ShuffleRDD的转换。这相当于groupByKey
后跟map
进行按键减少(检查this为什么使用groupByKey
效率低下)。
另一方面,treeAggregate
是reduce
函数的推广,受AllReduce
启发。这是火花意义上的“动作”,在主节点上返回结果。正如您在问题中发布的链接所解释的那样,在执行本地缩减操作之后,reduce
在主服务器上执行其余的计算,这可能非常繁琐(尤其是在reduce函数导致大向量或者矩阵)。相反,treeReduce
使用reduceByKey
并行执行减少(这是通过动态创建键值对RDD来完成的,其中键由树的深度决定;检查实现{{3 }})。
因此,要回答您的前两个问题,您必须使用reduceByKey
来计算字数,因为您有兴趣获取每个字数,treeReduce
不适合此处。其他两个问题与此主题无关。