Apache Spark-实现分布式QuadTree



我真的,真的,是Apache Spark的新手。

我正在Spark上以分布式方式实现近似LOCI(或ALOCI(,这是一种异常检测算法。该算法基于将点存储在QuadTree中,QuadTree用于查找点的邻居数量。

我很清楚QuadTrees是如何工作的。事实上,我最近已经在Java中实现了这样一个结构。但我完全迷失了这样一个结构在Spark上以分布式方式工作的方式。

类似于我需要的东西可以在地球公园找到。

https://github.com/DataSystemsLab/GeoSpark/tree/b2b6f1d7f0015d5c9d663a7b28d5e1bb1043c413/core/src/main/java/org/datasyslab/geospark/spatialPartitioning/quadtree

GeoSpark在许多情况下使用PointRDD类,该类扩展了SpatialRDD类。我可以看到,该类使用上面链接中的QuadTree来划分Spatial对象。这是我所理解的,至少在理论上是这样。

在实践中,我仍然无法理解这一点。举个例子,我在csv中有数百万条记录,我想在QuadTree中读取并加载它们。

我可以把csv读成RDD,但后来呢?这个RDD如何在逻辑上连接到我试图构建的QuadTree?

当然,我不希望这里有一个有效的解决方案。我只需要这里的逻辑来填补我脑海中的空白。如何实现分布式QuadTree以及如何使用它?

好吧,很遗憾,这个问题没有答案,但两周后我就有了一个可行的解决方案。不过,不能100%确定这是否是正确的方法。

我创建了一个名为Element的类,并将csv的每一行都转换为RDD[Element]。然后,我创建了一个名为QuadNode的可序列化类,它有一个List[Elements]和一个大小为4的Array[String]。在向节点添加元素时,这些元素会添加到节点的列表中。如果列表中包含超过X个元素(在我的情况下为20个(,则节点将分解为4个子节点,并将这些元素发送给子节点。最后,我创建了一个类QuadTree,它的其余属性中有一个RDD[QuadNodes]。每次节点断开为子节点时,这些子节点都会添加到树的RDD中。

在非函数语言中,每个节点将有4个指针,每个子节点一个。由于我们处于分布式环境中,因此这种方法不起作用。因此,我给每个节点一个唯一的Id。根节点有一个Id="0"。根节点的ID为"00"、"01"、"02"one_answers"03"。节点-"00"子级具有ID"000"、"001"、"002"、"003"。通过这种方式,如果我们想找到一个节点的所有子节点,我们可以通过检查节点的id是否启动来过滤树的RDD[QuadNode]。去掉节点id。颠倒这种逻辑可以帮助我们找到节点的父节点。

这就是我实现QuadTree的方式,至少目前是这样。如果有人知道更好的方法来实现这一点,我很想听听他/她的意见。

最新更新