簡體   English   中英

Neo4j 數據加載性能:驅動程序與自定義程序

[英]Neo4j data loading performance: driver vs custom procedure

我正在從 Neo4j Java 自定義過程切換到基於 Neo4j ZD52387880E1EA213817A 驅動程序的方法我想以某種微服務結束運行我的圖形算法,而不是通過 Cypher 調用自定義過程。 我使用一堆標准的 HashMaps 實現了遍歷:一旦數據從 Neo4j 加載到這些 HashMaps 中,圖遍歷比我原來的自定義過程快得多,所以這是非常有前途的。

現在我的問題是:在自定義過程中,我能夠將圖形(40 個 mio 邊,10 個 mio 節點)加載到哈希圖中,如下所示:

@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);
}

這需要太多時間,即使我使用 cypher 查詢將返回的節點數限制在幾千個。 我從來沒有等待完整的圖表加載。

與存儲過程相比,使用驅動程序(或替代方法)獲得相同速度的最佳選擇是什么? 是否存在會抑制這一點的基本限制?

請記住,過程代碼在服務器本身上執行,它有效地嵌入了 Neo4j。

將其與通過網絡傳輸所有節點及其屬性的需要進行比較。 這是過程不需要的大量額外 I/O。

正如 InverseFalcon 所指出的,通過 Bolt 協議的傳輸具有速度限制,而在程序中不存在。 我正在尋找的是這里描述的嵌入式 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 應用程序的上下文中使用它(因為它沒有作為自定義過程實現)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM