Neo4j 超级节点问题 - 扇出模式
Posted
技术标签:
【中文标题】Neo4j 超级节点问题 - 扇出模式【英文标题】:Neo4j super node issue - fanning out pattern 【发布时间】:2015-02-18 12:29:19 【问题描述】:我是图形数据库领域的新手,正在研究 Neo4j 并学习 Cypher,我们正在尝试对图形数据库进行建模,这是一个相当简单的模型,我们有用户,我们得到了电影,用户可以查看 电影,评分 电影,创建播放列表,播放列表可以拥有 电影。
问题是关于超级节点性能问题。我将引用我目前正在阅读的一本非常好的书 - Rik Van Bruggen 的《Learning Neo4j》,所以这里是:
然后在数据集中出现一个非常有趣的问题,其中图表的某些部分 都连接到同一个节点。该节点,也称为密集节点或 超级节点,成为图遍历的真正问题,因为图数据库 管理系统必须评估所有相关的关系 该节点以确定图遍历中的下一步。
书中提出的解决这个问题的方法是让一个 Meta 节点有 100 个连接,并将第 101 个连接链接到一个新的 Meta 节点,该节点链接到之前的 Meta 节点。
我在 Neo4j 官方博客上看到了一篇博文,说他们将在未来解决这个问题(博文来自 2013 年 1 月)-http://neo4j.com/blog/2013-whats-coming-next-in-neo4j/
他们说的更准确:
我们围绕“更大数据”计划的另一个项目是添加一些特定的优化来处理跨密集连接节点的遍历,这些节点具有非常大量(数百万)的关系。 (这个问题有时被称为“超级节点”问题。)
您对这个问题有什么看法?我们应该采用元节点扇出模式还是采用每个教程似乎都在使用的基本关系?还有其他建议吗?
【问题讨论】:
【参考方案1】:更新 - 2020 年 10 月。 This article is the best source on this topic,涵盖超级节点的方方面面
(下面是我的原始答案)
这是个好问题。这不是一个真正的答案,但为什么我们不能在这里讨论这个问题?从技术上讲,我认为我应该将您的问题标记为“主要基于意见”,因为您明确征求意见,但我认为值得讨论。
无聊但诚实的答案是它始终取决于您的查询模式。如果不知道您将针对这种数据结构发出什么样的查询,就真的无法知道“最佳”方法。
超级节点也是其他领域的问题。图数据库有时在某些方面很难扩展,因为其中的数据很难分区。如果这是一个关系数据库,我们可以垂直或水平分区。在具有超级节点的图形数据库中,一切都与其他一切“接近”。 (阿拉斯加农民喜欢 Lady Gaga,纽约银行家也喜欢)。不仅仅是图遍历速度,超级节点对于各种可扩展性来说都是一个大问题。
Rik 的建议归结为鼓励您创建超级节点的“子集群”或“分区”。对于某些查询模式,这可能是一个好主意,我并没有反对这个主意,但我认为这里隐藏着聚类策略的概念。您分配了多少个元节点?每个元节点的最大链接数是多少?你是如何将这个用户分配给这个元节点的(而不是其他的)?根据您的查询,这些问题将很难回答、难以正确实施,或两者兼而有之。
一种不同(但在概念上非常相似)的方法是克隆 Lady Gaga 大约一千次,复制她的数据并在节点之间保持同步,然后在克隆之间断言一堆“相同”关系。这与“元”方法没有什么不同,但它的优点是将 Lady Gaga 的数据复制到克隆,并且“元”节点不仅仅是导航的愚蠢占位符。但大多数相同的问题都适用。
这里有一个不同的建议:这里有一个大规模的多对多映射问题。如果这对您来说是一个非常大的问题,您最好将其分解为一个具有两列(from_id, to_id)
的关系表,每列都引用一个neo4j 节点ID。然后,您可能拥有一个主要是图形的混合系统(但有一些例外)。这里有很多权衡;当然,您根本无法在密码中遍历该 rel,但它会更好地扩展和分区,并且查询特定 rel 可能会更快。
这里有一个普遍的观察:无论我们谈论的是关系、图形、文档、K/V 数据库还是其他什么——当数据库变得非常大,并且性能要求变得非常强烈时,人们几乎不可避免地会结束使用一种以上的 DBMS 提供某种混合解决方案。这是因为一个不可回避的现实,所有数据库都擅长某些事情,而不擅长其他事情。因此,如果您需要一个在所有方面都做得很好的系统,您将不得不使用不止一种数据库。 :)
在这些情况下,neo4j 可能可以做很多优化,但在我看来,系统需要一些关于访问模式的提示才能做得很好。在现有的 2,000,000 条关系中,端点如何实现最佳集群?旧关系是否比新关系更重要,反之亦然?
【讨论】:
感谢您的回答,阅读了几次,我们希望 Neo4j 为整个平台提供动力,与 SQL 数据库进行了大量合作,我们需要回答的一些问题将相当简单:"获取用户拥有的所有播放列表以及该播放列表中的所有电影”或“获取我喜欢的所有电影”,我担心与 mysql 对应项相比,“获取所有我喜欢的电影”问题的答案会有MySQL 中的 0.001 答案和 Neo4j 中的巨大答案 对于这些查询,所有 neo 听起来都很好。这些查询听起来像是可能触及超级节点(如果我最喜欢的电影之一非常受欢迎),但不会浏览超级节点。一个不好的查询可能是“给我看所有喜欢肖申克的救赎的人喜欢的电影”。【参考方案2】:回复。 Neo4j 博客,Neo4j 2.1(及更高版本)应增强对密集节点的支持,另请参阅http://neo4j.com/blog/neo4j-2-1-graph-etl/
【讨论】:
【参考方案3】:(免责声明:不是答案,而是一些讨论)
您提到的 2013 neo4j 博客文章链接到此github commit,其中讨论了预期的问题范围及其解决方案。总而言之,它没有解决一般的supernode
问题。相反,当supernode
拥有的多种关系类型(和方向)中,某些类型(方向)碰巧比其他类型(方向)具有不成比例的边缘时,它可以缓解问题。该引擎能够根据类型和方向进行过滤。
一个更通用的解决方案是来自 Titan (https://***.com/a/21385213/1311956) 的 vertex centric
方法,它按一个或多个属性对边缘进行排序,导致 O(log(E)) 搜索性能,其中 E 是数字进/出supernode
的边数。
Neo4j 有关系索引的概念。与 Titan 的 vertex centric
方法不同,该索引是全局的。然而,关系索引是 Neo4j 中的遗留索引。这在另一个*** thread 中进行了讨论。
Supernode
的另一个问题是导致存储问题和 IO 成本的存储问题。
【讨论】:
以上是关于Neo4j 超级节点问题 - 扇出模式的主要内容,如果未能解决你的问题,请参考以下文章