【问题标题】:Neo4j LOAD CSV extremely slow when merging relations from a label of 3mil nodes to a lable of 20 nodes将关系从 30 万个节点的标签合并到 20 个节点的标签时,Neo4j LOAD CSV 非常慢
【发布时间】:2015-04-10 22:28:21
【问题描述】:

neo4j 2.2.0 在一个 3 机器集群中,具有约 300 万个“用户”节点和约 10 个“品牌”节点

当加载大约 20k 行“:LIKES”关系时:

USING PERIODIC COMMIT 30000
LOAD CSV WITH HEADERS FROM "file://path/to/my/file.csv" AS csvLine
MATCH (user:User {id: toInt(csvLine.userId)})
MATCH (brand:Brand {id: csvLine.brandId})
MERGE (user)-[:LIKES]->(brand)

它从来没有成功过。有时大约需要 6 分钟,然后导致主从交换并失败并出现错误“事务已终止”。其他时候需要超过 10 分钟并导致 http 事务重置。加载时观察到不寻常的垃圾收集模式。配置文件显示两个“MATCH”花费了很少的时间。所以应该是 MERGE 导致缓慢和最终失败。不幸的是,从配置文件中没有进一步显示在 MERGE 中做了什么导致缓慢。

节点计数和关系计数似乎都是合理的。加载将约 3 百万个节点链接到另外约 2 百万个节点的其他关系只需要几分钟。所以一个怀疑是,问题是由于同时将太多用户链接到太少的品牌? Neo4j 在这种情况下无法并行?为什么触发了这么多 GC?

我希望“配置文件”可以提供更多详细信息,例如每个部分花费了多少时间,以及如何进一步细分时间是如何花费在例如 Cypher 编译器或其他内核活动上的?有没有办法读取内部操作日志?

有什么建议或想法吗?谢谢!

【问题讨论】:

  • 您是否为:User(id):Brand(id) 创建了索引?
  • 你能分享你的解释输出吗? (停止定期提交以使其正常工作)。

标签: csv neo4j load cypher


【解决方案1】:

确保为:User(id):Brand(id) 提供索引或约束。

您也可以尝试将 MERGE 替换为 CREATE 并在之前断言唯一性

LOAD CSV WITH HEADERS FROM "file://path/to/my/file.csv" AS csvLine
WITH distinct toInt(csvLine.userId) as userId, csvLine.brandId as brandId
MATCH (user:User {id: userId})
MATCH (brand:Brand {id: brandId})
MERGE (user)-[:LIKES]->(brand)

也许你的品牌是一个密密麻麻的ndoe,你能试着扭转箭头的方向吗? MERGE (brand)<-[:LIKES]-(user)

【讨论】:

  • 反转 MERGE 没有帮助。
  • Michael,我无法为配置文件或 vm 可视化工具发布图像(还没有足够的声誉 :-( )...无论如何,“配置文件加载 csv”需要 589682 毫秒才能完成 MERGE , 在一个 100k 行的文件上。如果用返回替换 MERGE,只需要 12463 毫秒。100k 大小与其他关系很好地工作(即使 500k 也很快),但不是这个。我将 csv 文件分成多个较小的文件,然后重试。还有其他建议吗?
【解决方案2】:

感谢迈克尔和cybersam 的帮助。找到原因是密集节点上的 MERGE。在内部 neo4j 2.2.0 对具有相同关系的所有节点使用链表(2-way),新的 MERGE 意味着没有索引的 2 个链表扫描,因此随着更多关系的添加,扫描密集节点的列表将花费越来越长的时间.

我们的解决方法是在转储大量关系时使用 CREATE。然后定期在更小的数据集上使用 MERGE 更新。

但是问题仍然存在,并且并非总是可以创建。 neo说他们会改进它。

【讨论】:

  • “neo 说他们会改进它”:两年过去了,它仍然很慢
猜你喜欢
  • 1970-01-01
  • 2014-04-15
  • 2015-04-30
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多