以下是使用Apache Spark编写的Kmeans算法的一部分:
closest = data.map(lambda p: (closestPoint(p, kPoints), (p, 1)))
pointStats = closest.reduceByKey(lambda (x1, y1), (x2, y2): (x1 + x2, y1 + y2))
newPoints = pointStats.map(lambda (x, (y, z)): (x, y / z)).collect()
任何人都可以向我解释它是如何工作的?假设我们有两个集群和1000个点,我们希望在具有两个从节点和一个主节点的集群中运行它。我认为第一个函数(最接近的)可以被认为是映射器,第二个函数可以是组合器,但是最后一个函数应该是什么呢?哪一个充当减速器?
答案 0 :(得分:1)
您传递reduceByKey
一个可用作组合器和缩减器的函数,因为如果您的用例无法使用需要使用的组合器,则需要将其传递给聚合函数groupByKey
。是的,无论何时你在火花上的RDD上调用map
,你传递的函数都可以被视为一个映射器。你一定要看看RDD
docs和PairRDDFunctions
。请记住,火花程序往往会有多个映射和缩减阶段,因为它会尝试将中间输出保留在内存中,而标准Hadoop MapReduce每次都会从磁盘读取和写入磁盘。此外,如果您使用spark,可以使用k-means in MLlib
更新:
在参考你的评论时,他们将(总和/ num点)映射到每个从节点"是因为火花的工作方式意味着没有开销。由于spark为每个RDD使用DAG,因此在执行动作(例如在这种情况下为collect()
)之前不会计算任何内容,因此最后的地图实际上可以无缝地获得减速器的输出,这不应该是溢出到磁盘,因为它非常小。这类似于Hadoop中的ChainReducer
,但是在连接的RDD中,每一步都保存在内存中(显然这并不总是可行的,所以有时它会溢出到磁盘,这也取决于序列化级别)。因此,基本上最后的计算实际上将在与reducer相同的节点上完成(之后不需要随机播放),然后才收集给驱动程序。
答案 1 :(得分:1)
如果你想了解火花代码,首先要做的是了解k-means。作为高级概述,k-means执行以下步骤:
你的第一行是算法的第(2)步;你的第二行和第三行是算法的第(3)步。这两条线正在做的是找到集群中所有点的平均值。
决赛'收集'方法调用将数据从RDD移动到本地计算机(准备广播新的质心,退出Spark环境中的所有节点)。为了重复步骤(2)和(3),您必须将当前质心的知识分配给每个节点。