微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Neo4j 数据加载性能:驱动程序 vs 自定义程序

如何解决Neo4j 数据加载性能:驱动程序 vs 自定义程序

我正在从 Neo4j Java 自定义过程切换到基于 Neo4j Java 驱动程序的方法。我想最终得到某种运行我的图形算法的微服务,而不是通过 Cypher 调用自定义过程。我使用一堆标准的 HashMap 实现了遍历:一旦将数据从 Neo4j 加载到这些 HashMap 中,图遍历就比我原来的自定义过程要快得多,所以很有希望。

现在我的问题:在自定义过程中,我能够将图形(40 个 mio 边,10 个 mio 节点)加载到 Hashmap 中,如下所示:

@Context
public GraphDatabaseService db;
...

HashMap<Long,Long> mapNodeIdProperty = new HashMap<>();
db.beginTx().getAllNodes().stream().forEach((org.neo4j.graphdb.Node n) 
              -> mapNodeIdProperty.put(n.getId(),(Long) n.getProperty("combProp")));

这大约需要一分钟,我认为这是可以接受的服务启动时间。

现在,我能找到的使用驱动程序的最佳解决方案是这样的:

driver = GraphDatabase.driver( uri,AuthTokens.basic( user,password ) );

...

try ( Session session = driver.session() )
{
    String status = session.writeTransaction( new TransactionWork<String>()
    {
        @Override
        public String execute( Transaction tx )
        {
            Stream<Record> resultStream = (Stream<Record>) tx.run(
                           "MATCH (n) RETURN n").stream();
            resultStream.forEach((Record n) -> listNodes.add(((Record) n).get("n").asNode()));
            return "ok; length=" + listNodes.size();
        }
    });
    System.out.println( status);
}

这需要太多时间,即使我使用密码查询将返回节点的数量限制为只有几千个。我从来没有等待完整的图表加载。

与存储过程相比,使用驱动程序(或替代方法)获得相同速度的最佳选择是什么?是否存在会抑制这种情况的基本限制?

解决方法

请记住,过程代码在服务器本身上执行,它有效地嵌入了 Neo4j。

将其与通过网络传输所有节点及其属性的需求进行比较。这是过程不需要的大量额外 I/O。

,

正如 InverseFalcon 所指出的,通过 Bolt 协议的传输带有速度限制,而不存在于程序中。我正在寻找的是 here 所描述的嵌入式 DBMS。我现在这样使用它:

public class GraphAccess implements AutoCloseable
{
    ...

    private final DatabaseManagementService managementService =
        new DatabaseManagementServiceBuilder(NEO4J_DATA_PATH)
        .setConfig( GraphDatabaseSettings.read_only,true )
                        .setConfig(GraphDatabaseSettings.logs_directory,NEO4J_LOGS_DIRECTORY).build();
    public final GraphDatabaseService db = managementService.database( NEO4J_DATABASE_NAME );

    public final HashMap<Integer,String> mapNodeProp = new HashMap<>();

    ...

    private void getNodeData() {

        try ( Transaction tx = db.beginTx() ) {
            tx.getAllNodes().forEach((Node n) -> {
                
                final Integer nodeId = (int) n.getId();
                mapNodeProp.put(nodeId,(String) n.getProperty("name"));
            
            }
        }
    }
}

这具有吞吐量高的优点(因为它不使用驱动程序,而是直接访问neo4j 数据库数据)以及在 Spring 应用程序的上下文中使用它的可能性(因为它不是作为自定义过程实现的) ).

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。