2015-03-25 4 views
1

В настоящее время я работаю над проектом по внедрению базы данных Neo4j (V2.2.0) в области веб-аналитики. После загрузки некоторых образцов я пытаюсь загрузить большой набор данных (> 1 ГБ,> 4 М строк). Проблема, с которой я сталкиваюсь, заключается в том, что использование команды MERGE занимает экспоненциально больше времени по мере увеличения размера данных. Интернет-источники неоднозначны в отношении того, что лучший способ - загрузить большие наборы данных, когда не каждая строка должна быть загружена как узел, и я хотел бы получить некоторую ясность по этому вопросу. Чтобы подчеркнуть, в этой ситуации я просто загружаю узлы; отношения - следующий шаг.Команда MERGE Neo4j в больших наборах данных

В основном существует три метода

I) Установить ограничение уникальности для свойства, и создавать все узлы. Этот метод использовался главным образом до того, как была введена команда MERGE.

CREATE CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE 

следует

USING PERIODIC COMMIT 250 
LOAD CSV WITH HEADERS FROM "file:C:\\path\\file.tsv" AS row FIELDTERMINATOR'\t' 
CREATE (:Book{isbn=row.isbn, title=row.title, etc}) 

По моему опыту, это будет возвращать ошибку, если дубликат найден, который останавливает запрос.

ii) Объединение узлов со всеми их свойствами.

USING PERIODIC COMMIT 250 
LOAD CSV WITH HEADERS FROM "file:C:\\path\\file.tsv" AS row FIELDTERMINATOR'\t' 
MERGE (:Book{isbn=row.isbn, title=row.title, etc}) 

Я попытался загрузками своего сета таким образом, но после того, как позволить протекание процесса в течение более 36 часов, и приходить к останову, я полагал, что должна быть лучшей альтернативой, так как ~ 200K моего возможного ~ Загружено 750 тыс. Узлов.

iii) Объединение узлов на основе одного свойства и установка остального после этого.

USING PERIODIC COMMIT 250 
LOAD CSV WITH HEADERS FROM "file:C:\\path\\file.tsv" AS row FIELDTERMINATOR'\t' 
MERGE (b:Book{isbn=row.isbn}) 
ON CREATE SET b.title = row.title 
ON CREATE SET b.author = row.author 
etc 

Я бегу тест (~ 20К узлов), чтобы увидеть, если переключение от метода II к III позволит улучшить время выполнения, так как меньший образец дал противоречивые результаты. Существуют ли методы, которые я контролирую и могу улучшить время выполнения? Если я не ошибаюсь, пакетный вставщик работает только для команды CREATE, а не команды MERGE.

Я разрешил Neo4j использовать 4 ГБ ОЗУ, и, судя по моему диспетчеру задач, этого достаточно (используется чуть более 3 ГБ).

+0

AFAIK, метод iii) будет использовать индекс для поиска узла, тогда как метод ii) не будет (из-за сопоставления нескольких свойств). Вы также пытались увеличить количество операций в каждой транзакции до 1000, например? – albertoperdomo

+0

Сначала я опустил его, потому что думал, что Neo4j не справляется с загрузкой, когда я установил его на уровне 1000. После обнаружения реальной проблемы с этой установкой я не увеличил ее до 1000, поэтому я сделаю что снова –

ответ

1

Способ iii) должен быть самым быстрым решением, поскольку вы MERGE против одного объекта. Создаете ли вы ограничение уникальности, прежде чем делать MERGE? Без индекса (ограничение или нормальный индекс) процесс займет много времени с ростом числа узлов.

CREATE CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE 

Последовал:

USING PERIODIC COMMIT 20000 
LOAD CSV WITH HEADERS FROM "file:C:\\path\\file.tsv" AS row FIELDTERMINATOR'\t' 
MERGE (b:Book{isbn=row.isbn}) 
ON CREATE SET b.title = row.title 
ON CREATE SET b.author = row.author 

Это должно работать, вы можете увеличить PERIODIC COMMIT.

Я могу добавить несколько сотен тысяч узлов в течение нескольких минут таким образом.

+0

Удивительный! Эта комбинация значительно увеличивает время выполнения (16 секунд против 30 минут). Единственная проблема заключается в том, что она не загружает все данные из файла. Он загружает 20000 узлов, где метод ii) загружен 20506. Любая идея, как это вызвано? EDIT: объединение ограничения с методом ii возвращает ошибки в отношении уникального ограничения, так что это не опция –

+0

Если вы создаете ограничение уникальности на 'isbn', оба метода должны создавать одинаковое количество узлов (даже если ii) сливается с несколькими свойствами) , Попытайтесь уменьшить до 'PERIODIC COMMIT 1000' для тестирования. Сколько уникальных 'isbn' у вас есть в наборе тестовых данных? –

+0

Очевидно, что 20000 верен, так как добавление фиктивной строки в файл увеличивает количество узлов до 20001. Затем 20506 должно быть вызвано несогласованностью в данных –

0

В целом убедитесь, что у вас есть указатели на месте. Слейте узел сначала на основе индексированных свойств (для быстрого поиска), а затем измените свойства этого узла по мере необходимости с помощью SET.

Кроме того, оба ваших подхода проходят через уровень транзакции.Если вам нужно очень быстро забивать большое количество данных в БД, вы, вероятно, не хотите использовать транзакции для этого, потому что они предоставляют вам функциональные возможности, которые вам могут не понадобиться, и им требуются накладные расходы, которые замедляют вас. Таким образом, более крупным решением было бы не вставлять данные с LOAD CSV, но идти по другому маршруту целиком.

Если вы используете серию neo4j серии 2.2, вы можете пойти на batch inserter via java, или neo4j-import tool, к сожалению, недоступно до 2.2. У них обоих есть общее, что они не используют транзакции.

Наконец, в любом случае вы должны прочитать Michael Hunger's article on importing data into neo4j, так как это дает хорошее концептуальное обсуждение того, что происходит, и почему вам нужно пропустить транзакции, если вы собираетесь загружать большие огромные груды данных в neo4j.

+0

Спасибо за объяснение индексов и уровня транзакции. Я буду изучать инструменты где-нибудь на следующей неделе, так как дальнейшее улучшение времени выполнения более приветствуется. Сначала мне нужно закончить доказательство концепции своевременно, поэтому я предпочитаю работать с инструментами, с которыми я знаком до сих пор. –

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