Ремонт, сервис, услуги » Информация » Тестируем импорт данных в Neo4j




Тестируем импорт данных в Neo4j

Автор: addministr от 11-05-2022, 18:30

Категория: Информация



Neo4j без преувеличения самая распространенная графовая база данных. Подход «schema free», гибкий язык запросов «cypher» — познакомиться с ней стоит хотя бы для расширения кругозора. Мы в компании Bimeister провели серию экспериментов по переезду на Neo4j для повышения производительности. Под катом я рассмотрю одну из сторон возможного апгрейда — импорт данных в графовую БД, проведу оценку ее преимуществ и недостатков и оценю время загрузки каждым из способов.
Тестируем импорт данных в Neo4j
Если обратиться к документации, то СУБД предоставляет два основных способа импорта: загрузку CSV-файлов через утилиту администратора neo4j-admin и загрузку все тех же файлов запросом с клиента. Также есть третий способ, который не раскрыт в документации, но об этом чуть ниже. Для сравнения все варианты буду оценивать по следующим критериям:

возможность импорта на любом этапе цикла жизни БД;



возможность промежуточного сохранения результата;



возможность использования для массовых DM-операций;



возможность передачи данных в соединении.

NEO4J-ADMIN

Импорт с помощью утилиты администратора рассчитан на инициализацию пустой БД. Вы не сможете дописать или обновить уже созданную БД. Все данные необходимо разбить на вершины и связи в отдельные CSV-файлы. Импорт осуществляется одной транзакцией, передача данных — через файловую систему.

LOAD CSV

Импорт с оператором LOAD CSV возможен с клиента СУБД и рассчитан на порции данных до 10М записей. Есть возможность разбивать на транзакции в конструкции оператора. Этот вариант импорта можно сочетать с командами удаления и обновления данных. Основным требованием остается передача данных через CSV-файлы.

UNWIND

Третий способ загрузки заключается в возможности языка «cypher» работать с коллекциями и словарями c помощью оператора UNWIND. В качестве параметров запроса можно передавать коллекции, содержащие словари, содержащие коллекции, содержащие словари... ну, вы поняли. Таким образом можно импортировать коллекции вложенных объектов, передавать данные напрямую в соединении с СУБД и обрабатывать все одним запросом.

 



Жизненный цикл БД



Промежуточное сохранение



DM-операции



Данные в соединении



NEO4J-ADMIN



-



-



-



-



LOAD CSV



+



+



+



-



UNWIND



+



+



+



+

Сравнение скорости импорта

Для сравнения скорости загрузки использовались данные об иерархии ~1M объектов (~100K связей). Импорт через утилиту neo4j-admin и LOAD CSV требует подготовки файлов в формате CSV с заголовками:

Nodes (Uid,Title)



Edges (ParentId,ChildId)

NEO4J-ADMIN

Импорт с помощью утилиты администратора выполняется одной командой с указанием всех файлов:

docker run -v " $(pwd)/dаta:/data"
-e "NEO4J_dbms_directories_import:/import"
-v "$(pwd)/import:/import"
neo4j:4.4.3-community bin/neo4j-admin import
--nodes="Exemplar=/import/nodes.csv"
--relationships="HAS_COMPOSITION=/import/edges.csv"

LOAD CSV

Импорт с оператором LOAD CSV подразумевает загрузку каждого файла в отдельности. Для выполнения запросов можно воспользоваться утилитой «cypher-shell»:

docker run -v " $(pwd)/dаta:/data"
-e "NEO4J_dbms_directories_import:/import"
-v "$(pwd)/import:/import"
neo4j:4.4.3-community bin/cypher-shell

В первую очередь необходимо создать индекс на ключевое поле импортируемых вершин:



create constraint exemplar_uid for (n:Exemplar) require n.Uid is unique; 2. Загрузить вершины:

USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM 'file:///nodes.csv' as line
CREATE (:Exemplar {Uid: line.Uid, Title: line.Title});

Загрузить связи:



USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM 'file:///edges.csv' as line
MATCH (p:Exemplar {Uid: line.parentId}), (c:Exemplar {Uid: line.childId})
MERGE (p)-[:HAS_COMPOSITION]->(c);

UNWIND

Для импорта оператором UNWIND необходимо написать клиент на одном их поддерживаемых языков. Данные нужно сгруппировать в коллекцию объектов со связями. В моем случае возможны два способа:

{
"Uid": "...",
"Title": "...",
"ParentId": "..."
}Или
{
  "Uid": "...",
  "Title": "...",
  "ChildIds": [...]
}
  1. Также сперва стоит создать индекс:

create constraint exemplar_uid for (n:Exemplar) require n.Uid is unique;

В первом случае импорт выполняется запросом:

UNWIND $page as inExemplar
MERGE (c:Exemplar {Uid: inExemplar.Uid})
SET c.Title = inExemplar.Title
WITH c, inExemplar.ParentId as parentId
WHERE parentId is not null
MERGE (p:Exemplar {Uid: parentId})
MERGE (p)-[:HAS_COMPOSITION]->(c)

$page — параметр, в котором передается коллекция объектов.

Во втором случае:

UNWIND $page as inExemplar
MERGE (p:Exemplar {Uid: inExemplar.Uid})
SET p.Title = inExemplar.Title
WITH p, inExemplar.ChildIds as childIds
WHERE not isEmpty(childIds)
UNWIND childIds as childId
MERGE (c:Exemplar {Uid: childId})
MERGE (p)-[:HAS_COMPOSITION]->(c)В результате эксперимента были получены следующие результаты:

 



Время импорта



NEO4J-ADMIN



34s



LOAD CSV



1m 37s



UNWIND1



2m 07s



UNWIND2



2m 55s

В случае с импортом оператором UNWIND на скорость загрузки оказывает влияние способ группировки данных, наличие вложенных операций увеличивает время.

Вывод

Импорт через утилиту NEO4J-ADMIN и оператор LOAD CSV — это инструменты администратора, которые позволяют инициализировать или редактировать БД из консоли. Самый быстрый способ, с помощью утилиты администратора, имеет больше всего ограничений. Главный недостаток в этих подходах — передача данных через файловую систему. Такой способ требует дополнительных усилий по организации общего файлового хранилища между клиентом и сервером. В условиях, когда СУБД используется в микросервисной архитектуре, такое ограничение может быть весьма неприятным. С другой стороны, импорт с оператором UNWIND дает большую степень свободы при организации архитектуры приложения, хотя и показывает меньшую скорость загрузки. Для создания массовых DM операций оператор UNWIND, на мой взгляд, подходит наилучшим образом.

Литература



Рейтинг графовых бд: https://eandy.ru/oop/samye-populyarnye-grafovye-subd-dlya-c



LOAD JSON from URL AS dаta: https://neo4j.com/blog/cypher-load-json-from-url/



Efficient Neo4j Data Import Using Cypher-Scripts: https://medium.com/neo4j/efficient-neo4j-data-import-using-cypher-scripts-7d1268b0747



Fast Batched Updates of Graph Structures: https://medium.com/neo4j/5-tips-tricks-for-fast-batched-updates-of-graph-structures-with-neo4j-and-cypher-73c7f693c8cc



Data Import Decisions: Why Choose Kettle for Neo4j Data Import: https://jennifer-reif.medium.com/data-import-decisions-why-choose-kettle-for-neo4j-data-import-1bd91ab85300

 

Источник: https://habr.com/ru/company/bimeister/blog/665230/





Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Архив | Связь с админом | Конфиденциальность

RSS канал новостей     Яндекс.Метрика