Низкая производительность при сохранении данных в neo4j Enterprise Version (версия trail) - PullRequest
0 голосов
/ 28 июня 2018

Построить 3 узла кластера в среде тестирования и использовать соединение Neo4j-JDBC для сохранения данных JSON в Neo4j.

При создании только 2000 узлов и 2000 отношений через статистику JSON: Общее время сохранения данных топологии в Neo4j: 456688 мс и размер ссылок: 2000, размер узлов: 2000.

Сохранено без проверки дублирования узлов / отношений (удалены методы checkVertex и checkRelation):

Общее время сохранения данных топологии в Neo4j: 446979 мс и размер ссылок: 2000, размер узлов: 4000 (Поскольку мы не проверяем дублирование, были созданы двойные узлы).

Код:

public Connection getConnection(String masterNodeIp, String password) throws Exception {         

 return(Connection)DriverManager.getConnection("jdbc:neo4j:http://"+masterNodeIp+"/?user=neo4j,password="+password+"");

}

// Перебирая края, добавляем исходный и целевой узлы.

    try {
    for (Links link : topology.getL2links()) {
      if(conn != null) {
        long srcId = etGraphIdByUniquenessOfOrphan(clientId,link.getSrcMgmtIP());
        GraphId srcGraphId = prepareGraphId(srcId, "DEVICE");
        long tgtId = etGraphIdByUniquenessOfOrphan(clientId,link.getTgtMgmtIP());
        GraphId tgtGraphId = prepareGraphId(tgtId, "DEVICE");
        String srcQuery = createNode(conn, link, false,clientId,discProfileId, 
                          srcGraphId);          
        if(srcQuery!=null && !srcQuery.isEmpty()) 
            stmt.execute(srcQuery);                         
        String tgtQuery = createNode(conn, link, true,clientId,discProfileId, 
                          tgtGraphId);
        if(tgtQuery != null && !tgtQuery.isEmpty()) 
            stmt.execute(tgtQuery);
        String relationQuery = processRelation(conn, link,srcGraphId,tgtGraphId);
        if(relationQuery!=null && !relationQuery.isEmpty())
            stmt.execute(relationQuery);
        }
    }
} catch(Exception e) {
    System.out.println("Exception in processJsonData ::: "+e.getMessage());
    throw e;
} finally {
    stmt.close();
    conn.close();
}

// Перед созданием узла проверяется, существует ли узел уже или нет, чтобы избежать дублирования

private boolean checkVertex(Connection conn, String ip, String hostName, long clientId, long discPId, GraphId graphId) throws Exception{
    Statement stmt = null;
    ResultSet rs = null;
    boolean result=false;
    try {           
        stmt = conn.createStatement();          
        StringBuffer queryBuffer = new StringBuffer();
        queryBuffer.append(" MATCH (node) WHERE node.id ='"+graphId.getId()+"' AND node.sourceType = '"+graphId.getSourceType()+"'");
        queryBuffer.append(" RETURN node");
        rs = (ResultSet) stmt.executeQuery(queryBuffer.toString());
        while(rs.next()) {
            result=true;
            break;
        }
    } catch(Exception e) {
        System.out.println("Exception in fetching node ::: "+e.getMessage());
        throw e;
    } finally {
        rs.close();
        stmt.close();
    }

    return result;
}

// Перед созданием Relation также проверяется дублирование связей.

private boolean checkRelation(Connection conn, Links link, GraphId srcGraphId, GraphId tgtGraphId) throws SQLException {
    Statement stmt = null;
    ResultSet rs = null;
    boolean result=false;
    try {
        stmt = conn.createStatement();          
        StringBuffer queryBuffer = new StringBuffer();
        queryBuffer.append(" MATCH (src:resource)-[r:topology]->(tgt:resource) WHERE src.id='"+srcGraphId.getId()
            +"' AND tgt.id='"+tgtGraphId.getId()+"' AND r.srcInt='"+link.getSrcInt()+"'AND r.tgtInt='"+link.getTgtInt()+"'");
        queryBuffer.append(" RETURN r");
        rs=(ResultSet) stmt.executeQuery(queryBuffer.toString());
        while(rs.next()) {
            result=true;
            break;
        }
    }
    catch(Exception e) {
        System.out.println("Exception in fetching node ::: "+e.getMessage());
    } finally {
        rs.close();
        stmt.close();
    }
    return result;
}

Мы создали индексы для этих запросов на проверку дублирования, но производительность по-прежнему низкая.

А также, пожалуйста, дайте нам знать, как использовать уникальное ограничение «Ключ узла» на уровне Java, чтобы мы могли пропустить один раз запрос checkVertex. Мы пытались перехватить «constraintViolationexception» и добавили журнал вместо того, чтобы его выбросить, но это исключение, при котором не сохраняются никакие узлы.

1 Ответ

0 голосов
/ 29 июня 2018

Есть много вещей, которые вы можете улучшить:

  1. для массового импорта данных используйте драйвер Java напрямую, JDBC добавляет слой косвенности
  2. Используйте параметры!
  3. Использовать пакетирование с UNWIND или путем выполнения нескольких подготовленных состояний как пакет
  4. Не конструировать запросы с литеральными значениями.
  5. Убедитесь, что у вас есть индексы / ограничения для ваших ключей. В ваших запросах нет индексов, потому что вы не указали меток!
  6. Используйте MERGE, если вы не хотите иметь исключения из ограничений.
  7. Никогда не используйте StringBuffer.
  8. Использование try-with-resources
  9. Использовать executeUpdate

для дозирования: https://medium.com/@mesirii/5-tips-tricks-for-fast-batched-updates-of-graph-structures-with-neo4j-and-cypher-73c7f693c8cc

Для параметров: http://neo4j -contrib.github.io / Neo4j-JDBC / # _ minimum_viable_snippet

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...