neo4j cypher shell - исключение ограничения памяти - PullRequest
0 голосов
/ 23 марта 2020

Я новичок ie для neo4j. Я провел некоторое исследование, прежде чем опубликовать этот вопрос здесь, но не смог найти решение, которое работает для меня. У меня есть VM Ubuntu с 32 ГБ оперативной памяти. В настоящее время я использую neo4j-Community Edition 4.0.2 и получил настройки ниже в моем файле neo4j.conf.

dbms.memory.heap.initial_size=5120m
dbms.memory.heap.max_size=5120m
dbms.memory.pagecache.size=10g

Я пытаюсь импортировать файлы CSV в базу данных neo4j по умолчанию, используя оболочку cypher. Это хорошо работает для небольших файлов, но у меня проблема с CSV-файлами размером> 1 ГБ. Сбой с ошибкой ниже

Невозможно выделить 524288 байт из-за превышения лимита памяти; used = 2147266560, max = 2147483648

Я попытался установить JAVA_OPTS = -Xmx4G, чтобы увеличить пространство кучи java, но все равно не удается с той же ошибкой. Может кто-нибудь, пожалуйста, помогите? Утилита cypher-shell ищет больше места в куче или база данных neo4j ищет дополнительное пространство в куче? Если cypher-shell не может быть использован для импорта огромных файлов, каковы другие варианты импорта огромных файлов?

edit: Я использую commiti periodi c для каждых 200 строк и У меня есть приведенный ниже скрипт cypher в файле .cypher и использующий оболочку cypher для запуска файла .cypher

CREATE INDEX ON:Review (nr);

USING PERIODIC COMMIT 200 LOAD CSV WITH HEADERS FROM "file:///12Review.csv" AS row 
MERGE (R:Review {nr: toInteger(row.nr)}) 
WITH row, R
FOREACH(ignoreMe in CASE WHEN row.reviewDate IS NULL THEN [] ELSE [1] END| SET R.reviewDate =row.reviewDate)
FOREACH(ignoreMe in CASE WHEN row.title IS NULL THEN [] ELSE [1] END| SET R.title = row.title)
FOREACH(ignoreMe in CASE WHEN row.rating1 IS NULL THEN [] ELSE [1] END| SET R.rating1 =row.rating1) 
FOREACH(ignoreMe in CASE WHEN row.rating2 IS NULL THEN [] ELSE [1] END| SET R.rating2 =row.rating2) 
FOREACH(ignoreMe in CASE WHEN row.rating3 IS NULL THEN [] ELSE [1] END| SET R.rating3 =row.rating3) 
FOREACH(ignoreMe in CASE WHEN row.rating4 IS NULL THEN [] ELSE [1] END| SET R.rating4 =row.rating4)

1 Ответ

0 голосов
/ 24 марта 2020

Я запускаю EXPLAIN для этого и вижу оператор Eager в плане запроса, который в основном отменяет фиксацию periodi c и вызывает проявление всех результатов в памяти, что приводит к операции out of heap. Это вызывает FOREACH, вы не сможете использовать этот подход при использовании periodi c commit.

Вместо этого попробуйте использовать coalesce(), чтобы использовать первое ненулевое значение, сначала пытаясь получить значение строки, затем используйте значение узла:

USING PERIODIC COMMIT 10000 LOAD CSV WITH HEADERS FROM "file:///12Review.csv" AS row 
MERGE (R:Review {nr: toInteger(row.nr)}) 
SET R.reviewDate = coalesce(row.reviewDate, R.reviewDate),
R.reviewDate = coalesce(row.title, R.title),
R.reviewDate = coalesce(row.rating1, R.rating1),
R.reviewDate = coalesce(row.rating2, R.rating2),
R.reviewDate = coalesce(row.rating3, R.rating3),
R.reviewDate = coalesce(row.rating4, R.rating4)
...