26

我是图形数据库场景的新手,正在研究 Neo4j 并学习 Cypher,我们正在尝试对图形数据库进行建模,这是一个相当简单的模型,我们有用户,我们有电影用户可以观看 电影评价 电影,创建播放列表播放列表可以 电影

问题是关于超级节点性能问题。我将引用我目前正在阅读的一本非常好的书——Rik Van Bruggen 的 Learning Neo4j 中的一些内容,所以这里是:

然后在图的某些部分都连接到同一个节点的数据集中会出现一个非常有趣的问题。这个节点,也称为密集节点或超级节点,成为图遍历的一个真正问题,因为图数据库管理系统必须评估与该节点的所有连接关系,以确定下一步将是什么图遍历。

书中提出的解决这个问题的方法是让一个 Meta 节点有 100 个连接,并将第 101 个连接链接到一个新的 Meta 节点,该节点链接到之前的 Meta 节点。

DENSE_LIKES 扇出

我看到官方 Neo4j 博客的一篇博文说他们将在未来解决这个问题(博文来自 2013 年 1 月) - http://neo4j.com/blog/2013-whats-coming-next-在neo4j/

更确切地说,他们说:

我们围绕“更大数据”计划的另一个项目是添加一些特定的优化来处理跨密集连接节点的遍历,这些节点具有非常大量(数百万)的关系。(这个问题有时被称为“超级节点”问题。)

你对这个问题有什么看法?我们应该采用元节点扇出模式还是采用每个教程似乎都在使用的基本关系?还有其他建议吗?

4

3 回答 3

28

更新 - 2020 年 10 月这篇文章是这个话题的最佳来源,涵盖了超级节点的方方面面。

(下面是我的原始答案)

这是个好问题。这不是一个真正的答案,但为什么我们不能在这里讨论这个问题?从技术上讲,我认为我应该将您的问题标记为“主要基于意见”,因为您明确征求意见,但我认为值得讨论。

无聊但诚实的答案是它总是取决于您的查询模式。如果不知道您将针对此数据结构发出什么样的查询,则实际上无法知道“最佳”方法。

超级节点也是其他领域的问题。图数据库有时在某些方面很难扩展,因为其中的数据很难分区。如果这是一个关系数据库,我们可以垂直或水平分区。在具有超级节点的图形数据库中,一切都与其他一切“接近”。(阿拉斯加农民喜欢 Lady Gaga,纽约银行家也喜欢)。不仅仅是图遍历速度,超级节点对于各种可扩展性来说都是一个大问题。

Rik 的建议归结为鼓励您创建超级节点的“子集群”或“分区”。对于某些查询模式,这可能是一个好主意,我并没有反对这个主意,但我认为这里隐藏着聚类策略的概念。您分配了多少个元节点?每个元节点的最大链接数是多少?你是如何将这个用户分配给这个元节点的(而不是其他的)?根据您的查询,这些问题将很难回答,难以正确实施,或两者兼而有之。

一种不同(但在概念上非常相似)的方法是克隆 Lady Gaga 大约一千次,复制她的数据并在节点之间保持同步,然后在克隆之间断言一堆“相同”关系。这与“元”方法没有什么不同,但它的优点是将 Lady Gaga 的数据复制到克隆中,并且“元”节点不仅仅是导航的愚蠢占位符。大多数相同的问题都适用。

不过,这里有一个不同的建议:这里有一个大规模的多对多映射问题。如果这对您来说是一个非常大的问题,您最好将其分解为一个具有两列的关系表(from_id, to_id),每列都引用一个 neo4j 节点 ID。然后,您可能拥有一个主要是图形的混合系统(但有一些例外)。这里有很多权衡;当然,您根本无法在密码中遍历该 rel,但它会更好地扩展和分区,并且查询特定 rel 可能会快得多。

这里有一个普遍的观察:无论我们是在谈论关系、图形、文档、K/V 数据库还是其他什么——当数据库变得非常大,并且性能要求变得非常强烈时,人们最终几乎不可避免地会遇到一些一种具有多种 DBMS 的混合解决方案。这是因为一个不可回避的现实,所有数据库都擅长某些事情,而不擅长其他事情。因此,如果您需要一个在所有方面都做得很好的系统,您将不得不使用不止一种数据库。:)

在这些情况下,neo4j 可能可以做很多优化,但在我看来,系统需要一些关于访问模式的提示才能做得很好。在现有的 2,000,000 条关系中,端点如何实现最佳集群?旧关系是否比新关系更重要,反之亦然?

于 2014-12-19T16:03:52.410 回答
2

关于。Neo4j 博客,应在 Neo4j 2.1(及更高版本)中增强对密集节点的支持,另请参见http://neo4j.com/blog/neo4j-2-1-graph-etl/

于 2014-12-26T19:20:47.363 回答
0

(免责声明:不是答案,而是一些讨论)

您提到的 2013 neo4j 博客文章链接到此github 提交,其中讨论了预期的问题范围及其解决方案。总而言之,它没有解决一般supernode问题。相反,当 a 拥有的多种关系类型(和方向)中supernode,某些类型(方向)碰巧比其他类型(方向)具有不成比例的边缘时,它可以缓解问题。该引擎能够根据类型和方向进行过滤。

一个更通用的解决方案是vertex centric来自 Titan ( https://stackoverflow.com/a/21385213/1311956 ) 的方法,它通过一个或多个属性对边缘进行排序,导致 O(log(E)) 搜索性能,其中E 是进/出的边数supernode

Neo4j 有关系索引的概念。与vertex centricTitan 的方法不同,该指数是全球性的。然而,关系索引是 Neo4j 中的遗留索引。这在另一个stackoverflow 线程中进行了讨论。

另一个问题Supernode是导致存储问题和 IO 成本的存储问题。

于 2016-03-03T19:55:49.430 回答