Apache Spark - 实现分布式四叉树

Posted

技术标签:

【中文标题】Apache Spark - 实现分布式四叉树【英文标题】:Apache Spark - Implementing a distributed QuadTree 【发布时间】:2018-11-08 23:06:39 【问题描述】:

我真的是 Apache Spark 的新手。

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

我确切地知道四叉树是如何工作的。其实我最近用Java实现了这样一个结构。但我完全迷失了这种结构在 Spark 上以分布式方式工作的方式。

可以在 Geospark 中找到与我需要的类似的东西。

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

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

在实践中,我仍然无法弄清楚这一点。例如,假设我在 csv 中有数百万条记录,我想在 QuadTree 中读取和加载它们。

我可以将 csv 读取到 RDD,但是然后呢?这个 RDD 如何在逻辑上连接到我正在尝试构建的 QuadTree?

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

【问题讨论】:

【参考方案1】:

好的,很遗憾,这个问题没有答案,但两周后我找到了一个可行的解决方案。不过,不能 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”和“03”。节点“00”子节点的 ID 为“000”、“001”、“002”、“003”。这样,如果我们想找到一个节点的所有后代,我们通过检查节点的 ids startWith out node id 来过滤我们的树的 RDD[QuadNode]。逆向这个逻辑可以帮助我们找到一个节点的父节点。

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

【讨论】:

以上是关于Apache Spark - 实现分布式四叉树的主要内容,如果未能解决你的问题,请参考以下文章

四叉树空间索引原理及其实现

四叉树实现中反向查找的成本/收益

Mark四叉树与八叉树

用于二维碰撞检测的四叉树

[地图开发][算法及数据结构]四叉树原理

LeetCode 0427「建立四叉树」