当从3mil节点的标签到20个节点的标签合并关系时,Neo4j LOAD CSV非常慢

时间:2015-04-10 22:28:21

标签: csv neo4j load cypher

<3> neo4j 2.2.0在一个3机群集中,约有3百万&#34;用户&#34;节点和~10&#34;品牌&#34;节点

加载~20k行时,&#34;:LIKES&#34;关系:

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分钟然后导致主从交换并且失败并且错误&#34;交易已经终止。&#34;其他时间花了超过10分钟并导致http事务重置。加载时观察到异常的垃圾收集模式。简介显示两个&#34; MATCH&#34; s花了很少的时间。所以它应该是导致缓慢和最终失败的MERGE。不幸的是,在配置文件中没有进一步说明在MERGE内部做了什么导致缓慢。

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

我希望&#34;个人资料&#34;可以告诉更多细节,例如每个部分花了多少时间,以及如何花费时间(例如Cypher编译器或其他内核活动)的进一步细分?有没有办法阅读内部操作日志?

有任何建议或想法吗?谢谢!

2 个答案:

答案 0 :(得分:1)

确保拥有:User(id):Brand(id)的索引或约束。

你也可以尝试用CREATE替换MERGE并在

之前断言唯一性
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)

答案 1 :(得分:0)

感谢Michael和cybersam的帮助。找到了在密集节点上成为MERGE的原因。内部neo4j 2.2.0对所有具有相同关系的节点使用链表(双向),新的MERGE表示2个链表扫描未编入索引,因此在密集节点列表上扫描需要更长时间随着更多关系的增加。

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

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