Мне нужно вставить огромное количество узлов с отношениями между ними в Neo4j через конечную точку REST API, около 5 тыс. Записей/с (все еще увеличивается).Оптимизация вставки больших объемов в Neo4j с использованием REST
Это будет непрерывная вставка 24x7. Каждой записи может потребоваться создание только одного узла, но для другого может потребоваться создание двух узлов и одного отношения.
Могу ли я улучшить производительность вставок, изменив мою процедуру или изменив настройки Neo4j?
Мой прогресс до сих пор:
1. Я тестировала с Neo4j на некоторое время, но я не мог получить производительность мне нужно было
окно Тест сервера: 24 ядер + 32GB RAM
Neo4j 2.0.0-M06 установлен как автономный сервис.
Запуск моего приложения Java на том же сервере (Neo4j и Java приложения должны работать на своем собственном сервере в будущем, поэтому встроенный режим не может быть использован)
REST API Endpoint.:/Дб/данные/batch (target:/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. Мои запросы и Cypher 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 (/ дб/данные/индекс/узел/Post единственность = get_or_create &/дб/данные/индекс/отношения/XXXXX ? uniqueness = get_or_create)
Из-за природы этих конечных точек конечного индекса (они возвращают местоположение данных в индексе вместо местоположения данных в реальном хранилище данных), поэтому я не мог использовать их в пакете (требуется функция связанного узла, созданного ранее в той же самой партии)
Я знаю, что могу включить auto_indexing и иметь дело с хранилищем данных непосредственно вместо устаревшего inde x, но они упомянули из 2.0.0, индекс схемы рекомендуется по устаревшему индексу, поэтому я решил перейти к подходу индекса пакетной + cypher + schema.
ОДНАКО, с пакетом + cypher, я могу получить только 200 описаний должностных обязанностей в секунду, это было бы намного выше, если бы MERGE с ограничениями всегда работал, скажем, около 600 ~ 800/с, но он все еще намного ниже 5 к/с. Я также пробовал индекс схемы без каких-либо ограничений, но в итоге он даже снизил производительность с точки зрения скорости вставки.
Вы использовали Streaming JSON? http://docs.neo4j.org/chunked/2.0.0-M06/rest-api-streaming.html. Следующая вещь, которая появляется у меня, касается использования устаревших конечных точек индекса. Вы все равно можете ссылаться на создание в другой пакетной операции. Пример. Создайте узел, используя uniquness get/create. Затем следующий элемент в пакете является cypher, который использует 'START n = node: IndexName (Key = {value}) ....'. Поэтому вы не можете ссылаться на него с помощью batchid, но вы все равно можете воспользоваться частью get/create. – LameCoder
Спасибо, LameCoder! Да, я посмотрел на потоковое видео и подумал, что это больше для восстановления с сервера, а не для отправки на сервер, поэтому я не пробовал, но сейчас я попробую. Кроме того, спасибо за советы по устаревшему индексу. :) – GoSkyLine
Спасибо @ plasmid87 за исправление моей орфографии, грамматики и форматирования. – GoSkyLine