Оптимизация пакетных вставок большого объема в Neo4j с помощью REST
Мне нужно вставить огромное количество узлов со связями между ними в Neo4j через конечную точку BEST API REST, около 5 тыс. Записей в секунду (все еще увеличивается).
Это будет непрерывная вставка 24х7. Каждая запись может потребовать создания только одного узла, но для другой может потребоваться создание двух узлов и одной взаимосвязи.
Могу ли я улучшить производительность вставок, изменив мою процедуру или изменив настройки Neo4j?
Мой прогресс до сих пор:
1. Я некоторое время тестировал Neo4j, но не смог получить нужную мне производительность
Тестовый сервер: 24 ядра + 32 ГБ ОЗУ
Neo4j 2.0.0-M06 установлен как автономный сервис.
Запуск моего Java-приложения на одном сервере. (Neo4j и Java-приложение должны будут запускаться на их собственных серверах в будущем, поэтому встроенный режим не может быть использован)
Конечная точка API REST: / db / data / batch (цель: / cypher)
Использование индекса схемы, ограничений, MERGE, CREATE UNIQUE.
2. Моя схема:
neo4j-sh (0)$ schema
==> Indexes
==> ON :REPLY(created_at) ONLINE
==> ON :REPLY(ids) ONLINE (for uniqueness constraint)
==> ON :REPOST(created_at) ONLINE
==> ON :REPOST(ids) ONLINE (for uniqueness constraint)
==> ON :Post(userId) ONLINE
==> ON :Post(postId) ONLINE (for uniqueness constraint)
==>
==> Constraints
==> ON (post:Post) ASSERT post.postId IS UNIQUE
==> ON (repost:REPOST) ASSERT repost.ids IS UNIQUE
==> ON (reply:REPLY) ASSERT reply.ids IS UNIQUE
3. Мои зашифрованные запросы и запросы JSON
3.1. Когда для одной записи требуется создание одного узла, описание задания выглядит следующим образом
{"method" : "POST","to" : "/cypher","body" : {"query" : "MERGE (child:Post {postId:1001, userId:901})"}}
3.2. Когда для одной записи требуется создать два узла с одним отношением, описание задания выглядит следующим образом
{"method" : "POST","to" : "/cypher","body" : {"query" : "MERGE (parent:Post {postId:1002, userId:902}) MERGE (child:Post {postId:1003, userId:903}) CREATE UNIQUE parent-[relationship:REPOST {ids:'1002_1003', created_at:'Wed Nov 06 14:06:56 AST 2013' }]->child"}}
3.3. Обычно я отправляю 100 описаний должностей (смешанные 3.1 и 3.2) на одну партию, для выполнения которой требуется около 150 ~ 250 мс
4. Проблемы с производительностью
4.1. Параллелизм:
/ db / data / batch (target: / cypher), по-видимому, не является поточно-ориентированным, протестировано с двумя или более одновременными потоками, что привело к остановке сервера Neo4j в течение секунд (секунд) ~ минут (ы).
4.2. MERGE с ограничениями не всегда работает.
При создании двух узлов и одной взаимосвязи с одним запросом (упомянутым выше в 3.2.) Он иногда работает как шарм; но иногда происходит сбой с CypherExecutionException и сообщается, что один из узлов xxxx уже существует с меткой aaaa и свойством "bbbbb" = [ccccc]; Насколько я понимаю, MERGE не предполагает возврата какого-либо исключения, а возвращает узел, если он уже существует.
В результате исключения произойдет сбой и откат всей партии, что повлияет на мою скорость вставки.
Я открыл вопрос в GitHub для этого вопроса,https://github.com/neo4j/neo4j/issues/1428
4,3. CREATE UNIQUE с ограничениями не всегда работает для создания отношений.
Это упоминается и в том же выпуске github.
4.4. Представление:
На самом деле, прежде чем я использую пакет с шифром, я попробовал унаследованную индексацию с помощью get_or_create (/ db / data / index / node / Post? Uniqueness = get_or_create & / db / data / index / Relations / XXXXX? Uniqueness = get_or_create)
Из-за природы этих устаревших конечных точек индекса (они возвращают местоположение данных в индексе, а не местоположение данных в реальном хранилище данных), поэтому я не мог использовать их в пакете (требовалась функция ссылающегося узла, созданного ранее в том же пакете )
Я знаю, что мог бы включить auto_indexing и работать с хранилищем данных напрямую, а не с устаревшим индексом, но они упоминали из 2.0.0, индекс схемы рекомендуется использовать вместо унаследованного индекса, поэтому я решил переключиться на подход пакетного + шифровального + индекса индекса.
ОДНАКО, с пакетом + шифр, я могу получить только около 200 описаний заданий в секунду, это было бы намного выше, если бы всегда работал MERGE с ограничениями, скажем, около 600 ~ 800 / с, но он все еще намного ниже, чем 5k. / с. Я также попробовал индекс схемы без каких-либо ограничений, это привело к еще более низкой производительности с точки зрения скорости вставки.