Java 扩展Neo4J以实现同步写入/合并查询

Java 扩展Neo4J以实现同步写入/合并查询,java,neo4j,Java,Neo4j,通过NodeJS,我将这些数据收集到Neo4J: 用户(id,登录名) 应用程序(id、标题) 机器(id、地址) 这是完全异步的。 这意味着,很多时候,我可以获得关于数据库中不存在的用户和应用程序的信息 所以,我需要在用户和应用程序中为每一行运行一个合并,以确保它们在数据库中,而不是创建项目,然后创建关系。在此之后,我可以建立关系 我正在发送到/cypher端点 params:{props:objects_array}, query:[ ' FOREACH (p IN {props}

通过NodeJS,我将这些数据收集到Neo4J:

  • 用户(id,登录名)
  • 应用程序(id、标题)
  • 机器(id、地址)
这是完全异步的。 这意味着,很多时候,我可以获得关于数据库中不存在的用户和应用程序的信息

所以,我需要在用户和应用程序中为每一行运行一个合并,以确保它们在数据库中,而不是创建项目,然后创建关系。在此之后,我可以建立关系

我正在发送到
/cypher
端点

params:{props:objects_array},
query:[
  ' FOREACH (p IN {props} | ',
  '   MERGE (u:user    {id:p._user_id})    SET u.id = p._user_id ',
  '   MERGE (a:app     {id:p._app_id})     SET a.id = p._app_id ',
  '   MERGE (m:machine {id:p._machine_id}) SET m.id = p._machine_id ',
  '   MERGE (u)-[:OPENED]->(a) ',
  '   MERGE (a)-[:USERS]->(u) ',
  '   MERGE (u)-[:WORK_IN]->(m) ',
  ' )',
].join("")
这是可行的,但速度太慢了。 我通过更改同步请求和每个请求的行来控制平衡

对于5个同时请求,每个请求500行,它会处理4个死锁错误,完成5000行需要2分钟

问题是它需要2个核心的CPU来处理99%(digitalocean 4gb RAM)的所有时间,我需要将其扩展到150个同时请求,而不仅仅是5个

我认为可能的解决办法是:

  • 垂直缩放到四核(暂时解决,而不是长时间解决)
  • 用于分发操作的数据库副本(这可能吗?)
  • 使用CREATE代替MERGE的一些方法。这是非常快,但我需要确保唯一的ID和不同的属性。也许使用约束
  • neo4j真的能够处理这么多的数据吗

如果只使用没有唯一约束或索引的MERGE,则需要Neo4j在每次合并时对节点空间进行完整扫描,以验证给定属性中不存在其他项。这意味着您最终的算法复杂度非常高,并且磁盘受限

您需要为在数据库中应该是唯一的标签/属性元组创建索引或(最好)唯一约束。这将大大加快合并查询的速度

此外,如果您使用新的事务端点(),它将取代cypher端点,您的情况会更好。它支持与cypher端点相同的功能,但提高了性能,提供了在每次HTTP调用中运行多个cypher语句的能力,并允许事务在服务器上保持运行,以便为客户端提供长期运行的事务支持


除此之外,Neo4j 2.1将在未来几个月内发布,它包含了一些性能增强功能,显著加快了并发查询的执行。您可能希望尝试即将到来的里程碑,看看这对您的性能有何帮助。

我不知道cypher,但使用neo4j rest api,您可以轻松实现这一点,也可以在同一批操作中与批中后续作业中创建的节点同时创建关系

您是否对:user、:app和:machine-like
在(u:user)ASSERT u上创建约束。\u user\u id是唯一的
?您是否尝试过使用事务端点?在询问neo4j是否能够处理它之前,还有很多事情要做;这些是第一个想到的,并且提供了更多的RAM,我认为这只是垃圾收集,在neo4j-wrapper.conf中有输出GC信息的配置设置。如果您只有两个cpu,您希望如何运行150个并行请求,如果两个cpu都很忙,那么它们无法接受更多的工作。并添加Jonathan上面提到的约束。@jjaderberg谢谢你的提示,他们帮了很多忙。有了约束和事务端点,我获得了更好的性能。20个同时请求,CPU使用率达到50~60%,感谢您的演示!有了约束和事务端点,我获得了更好的性能。在使用
/cypher
端点之前,我尝试了
/batch
,处理速度非常慢。谢谢