2013-06-13 3 views
2

У меня есть большое количество контактов и отношений, которые я пытаюсь вставить (многие миллионы). Чтобы ускорить это, я решил, что я буду их дозировать, а затем несколько потоков вставить их одновременно. Это вызовет несколько тупиков, но, поскольку я могу повторить их, у меня нет проблем с этим.Neo4j: утечка памяти блокировки

public void doBatch(final Collection<Object> rows) throws Exception { 
    int retryCount = 3; 
    while(!(retryCount<3)) { 
     Transaction tx = graphdb.beginTx(); 
     try { 
      for (Object row : rows) { 
       String[] fields = ((String) row).split(DELIMITER, -1); 
       if (fields.length < 4) { 
        log.error("Not enough fields to process row:" + row); 
       } else { 
        addLineToGraph(fields[0], fields[1], fields[2], fields[3]); 
       } 
      } 
      tx.success(); 
      retryCount = 0; 
     } catch (DeadlockDetectedException dead) { 
      tx.failure(); 
      retryCount--; 
      log.warn("Retry deadlock"); 
     } catch (Exception e) { 
      tx.failure(); 
      throw e; 
     } finally { 
      tx.finish(); 
     } 
    } 
} 

К сожалению, после нескольких часов работы и имея много тупиков, я бег из памяти (GC предел накладных превышен) даже после попытки 10G кучи. После анализа дамп стека я заметил много и много замков:

One instance of "org.neo4j.kernel.impl.transaction.RWLock" loaded by "sun.misc.Launcher$AppClassLoader @ 0xc0271350" occupies 672.139.928 (84,78%) bytes. 
The memory is accumulated in one instance of "java.util.HashMap$Entry[]" loaded by "<system class loader>". 

У меня впечатление, это вызвано неудавшихся сделок, не выпуская замки, так что я ограничить свой код в один поток, который будет убедиться, что нет происходит больше тупиков. После этого я вижу нормальные пилообразные диаграммы, вызванные сбором мусора, и больше ошибок в памяти. Из того, что я понимаю, tx.finish(); должен ли все очистить? Или я чего-то не хватает?

Я использую neo4j 2.0.0-M03 во встроенном режиме.

+1

А вы посмотрите на [вставки пакетной] (http://docs.neo4j.org/chunked/milestone/batchinsert.html)? Чтобы ускорить это, он не использует транзакции. – tstorms

+0

Мой код изначально был из старой версии neo4j. В то время было проблемой выполнять поиск по свойству узла во время пакетной обработки. Я не могу дублировать узлы с тем же свойством или схема становится бесполезной для меня. Поскольку набор данных довольно большой, я также не хочу создавать свой собственный индекс для сопоставления этих свойств с узлами. Надеюсь, это имеет смысл :) Я еще раз почитаю партию, чтобы узнать, можно ли это сделать в наши дни. –

+0

Насколько велика обычно одна партия? –

ответ

0

я повышен до 2.0.0-M05 и теперь я получаю различное поведение. Я получаю nullpointer в классе PersistenceWindowPool. По крайней мере, на данный момент этот класс не является идеальным потоком. Они сказали мне, что это будет разрешено в версии 2.0, но пока это не произойдет, я использую собственную синхронизированную версию этого класса.

https://github.com/bennies/neo4j/commit/d8a0f4732f347f2038ebace83c14d37d4b1f8691

Спасибо за все идеи это альтернативные решения :)

0

Что об использовании блокировки всякий раз, когда вы обновляете любое свойство узлов связи, а затем снять блокировку

Смежные вопросы