【问题标题】:Load Neo4J in memory on demand for heavy computations按需将 Neo4J 加载到内存中以进行繁重的计算
【发布时间】:2017-02-09 23:03:47
【问题描述】:

如何按需将 Neo4J 加载到内存中?

在我长期运行的工作的不同阶段,我将节点和关系与 Neo4J 保持一致。所以 Neo4J 应该在磁盘上,因为它可能会消耗太多的内存,而且我不知道我什么时候会对它运行读取查询。

但在某些时候(仅一次)我会想对我的 Neo4J 服务器运行非常繁重的读取查询,它的性能非常差(小时)。作为一种解决方案,我想将所有 Neo4J 加载到 RAM 以获得更好的性能。

什么是最好的选择?我应该使用运行盘还是有更好的解决方案?

附言

使用[r:LINK_REL_1*2] 查询工作得很快,[r:LINK_REL_1*3] 工作 17 秒,[r:LINK_REL_1*4] 工作超过 5 分钟,甚至不知道多少,因为我有 5 分钟超时。但我需要[r:LINK_REL_1*2..4] 查询才能在合理的时间内执行。

我的繁重查询说明

PROFILE
MATCH path = (start:COLUMN)-[r:LINK_REL_1*2]->(col:COLUMN) 
WHERE start.ENTITY_ID = '385' 
WITH path UNWIND NODES(path) AS col
WITH path, 
COLLECT(DISTINCT col.DATABASE_ID) as distinctDBs
WHERE LENGTH(path) + 1 = SIZE(distinctDBs)
RETURN path

更新了带有解释的查询(在测试中获得了相同的性能)

PROFILE
MATCH (start:COLUMN)
WHERE start.ENTITY_ID = '385' 
MATCH path = (start)-[r:LINK_REL_1*2]->(col:COLUMN)
WITH path, REDUCE(dbs = [], col IN NODES(path) | 
  CASE WHEN col.DATABASE_ID in dbs 
       THEN dbs 
       ELSE dbs + col.DATABASE_ID END) as distinctDbs
WHERE LENGTH(path) + 1 = SIZE(distinctDbs)
RETURN path

【问题讨论】:

  • 您能否解释一下“我想将所有 Neo4J 加载到 RAM”是什么意思?您需要在内存中按需存储整个 Neo4j 图吗?
  • 您正在运行的查询是什么?没有一个应该运行几个小时。
  • APOC 中也有一些图算法实现,可以将图的(部分)加载到纯内存结构中以运行算法。
  • @AnwarShaikh 我认为如果我将图形加载到 JVM 中,Neo4J 的性能应该会更好
  • @MichaelHunger 我更新了我的问题。由于大量排列,它是如此缓慢 - [r:FRIENDSHIP_REL*3] 返回 50,000 多个路径。但我需要[r:FRIENDSHIP_REL*2..5]

标签: java neo4j graph-databases in-memory-database


【解决方案1】:

APOC 程序有apoc.warmup.run(),它可能会将大部分 Neo4j 放入缓存中。看看这是否会有所作为。

【讨论】:

  • Neo4J 2.1.7 支持 APOC 吗?我已经阅读了您的答案stackoverflow.com/questions/39071324/…,但下面的 cmets 说 APOC 仅在内存中加载图形的一部分。我没有太大=大但非常密集的图表,不确定部分负载是否会让我感到很痛苦
  • 不,我相信自定义程序仅在 Neo4j 3.0 中引入,因此您将无法使用 APOC。
  • 3.0 之前的版本还有其他选择吗?您还可以假设将图形加载到 JVM 可以提高多少速度?
  • 实际上我要做一个概念证明。你能帮我弄清楚如何只加载:Person 节点和:FRIENDSHIP_RELapoc.warmup.run() 的关系吗?
  • 我不能将 Neo4J 加载到具有大页面大小的内存中吗?我在 2012 年看到了类似的问题,但他们没有描述他们是如何设法将图形加载到 RAM 的
【解决方案2】:

您似乎正在尝试创建一个查询,其中路径仅包含 :Persons from distinct countries。是这样吗?

如果是这样,我认为我们可以找到一个更好的查询,无需挂起即可执行此操作。

首先,让我们尝试一下容易实现的目标,看看避免 UNWIND 是否能有所作为。

PROFILE 或 EXPLAIN 查询,看看是否有任何数字与原始查询相比有显着差异。

MATCH (start:PERSON)
WHERE start.ID = '385' 
MATCH path = (start)-[r:FRIENDSHIP_REL*2..5]->(person:PERSON)
WITH path, REDUCE(countries = [], person IN NODES(path) | 
  CASE WHEN person.country in countries 
       THEN countries 
       ELSE countries + person.COUNTRY_ID END) as distinctCountries
WHERE LENGTH(path) + 1 = SIZE(distinctCountries)
RETURN path

【讨论】:

  • 我看到您更改了查询中的数据。如果您希望我将其更改为您的 COLUMN 和数据库 ID 模型,请告诉我。
  • 不,保留旧名称绝对可以。谢谢!我将在半小时内测试您的查询
  • 刚刚看到更新的计划,看起来我们在删除 UNWIND 时唯一避免的是将我们正在使用的行乘以中间某处,db hits 保持不变。我猜执行时间也差不多。
  • 是的,我刚刚完成了测试 - 执行时间保持不变
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
  • 2016-07-16
  • 2019-02-19
  • 1970-01-01
  • 2017-11-11
  • 2019-04-03
  • 2013-05-26
相关资源
最近更新 更多