Оптимизация пакетных вставок большого объема в 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. / с. Я также попробовал индекс схемы без каких-либо ограничений, это привело к еще более низкой производительности с точки зрения скорости вставки.

Ответы на вопрос(1)

Ваш ответ на вопрос