Neo4j LOAD CSV在合并从3mil节点标签到20节点标签的关系时速度极慢



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事务重置。加载时观察到异常的垃圾收集模式。个人资料显示,两次"比赛"花费的时间很少。因此,应该是并购导致了经济放缓和最终的失败。不幸的是,从侧面看,没有进一步显示MERGE内部所做的事情导致了缓慢。

节点数和关系数似乎都是合理的。加载将约3密耳节点链接到另一约2密耳节点的其他关系只需要几分钟。因此,有一种怀疑是,问题是由于同时将太多用户与太少品牌联系在一起吗?Neo4j在这种情况下不可能平行?为什么会触发这么多GC?

我希望"概要文件"能告诉我们更多的细节,比如每个部分花了多少时间,以及这些时间是如何花在Cypher编译器或其他内核活动上的?是否有读取内部操作日志的方法?

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

确保为: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)

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

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

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

最新更新