Многоклиентская массовая вставка Neo4j - очень низкая производительность REST - другие способы?

Я пытаюсь сравнить массивную вставку Neo4j в среде клиент-сервер. Пока я обнаружил, что есть только два способа сделать это:

  1. использовать ОТДЫХ
  2. внедрить серверное расширение

Я могу заранее сказать, что наш дизайн требует возможности вставки из многих одновременно запущенных процессов/машин, поэтому использование пакетной вставки с прямым подключением не вариант.

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

Я протестировал массовую вставку через REST всего с одного клиента, отправив 2 типа очень простых запросов Cypher:

create (vertex:V {guid: {guid}, vtype: {vtype}, random1: {random1}, random2: {random2} })

match (a:V {guid: {a} }) match (b:V {guid: {b} }) create (a)-[:label]->(b)

Поле Guid имело индекс.

На данный момент результаты очень плохие: (10k V + 40k E) за 13 минут по сравнению с конкурирующими продуктами, такими как Titan или Orient, которые предоставляют эффективный сервер из коробки и пропускная способность около (10 кВ + 40 кВ) в минуту.

Я пробовал более длительные транзакции и параметры запроса, но ни один из них не дал существенного выигрыша. Кроме того, накладные расходы от REST очень малы, поскольку я тестировал фиктивные запросы, и они выполняются намного быстрее (и клиент, и сервер находятся на одной машине). Я также пробовал вставлять из нескольких потоков - производительность не увеличивается.

Я нашел еще один вопрос StackOverflow, где советовали вставлять пакеты в большие запросы, содержащие тысячи команд, и периодически фиксировать. К сожалению, из-за характера того, как мы генерируем данные, пакетная обработка запросов невозможна. В идеале мы хотели бы, чтобы вставки были атомарными операциями и чтобы результаты появлялись сразу после их выполнения (на самом деле нет необходимости в транзакциях).

Таким образом, мои вопросы:

  1. оптимальны ли мои запросы Cypher для вставки?
  2. соответствуют ли результаты тому, что может быть достигнуто с помощью REST (или я могу выжать из REST гораздо больше)?
  3. Существуют ли другие способы эффективной многоклиентской массовой вставки?

person rohrl    schedule 04.02.2016    source источник
comment
{guid} совпадает с {a} или {b}? Кроме того, вы уже создали индекс (или ограничение уникальности) для :V(guid)?   -  person cybersam    schedule 04.02.2016
comment
Да, есть индекс в поле guid. Все 3 vars могут иметь разные значения, и эти 2 запроса будут выполняться отдельно. Однако когда я создаю ребро, я могу гарантировать, что обе вершины уже созданы.   -  person rohrl    schedule 04.02.2016
comment
Вы используете поддерживающие http-соединения?   -  person Michael Hunger    schedule 04.02.2016
comment
сколько одновременных клиентов и сколько ядер было на вашем сервере? у тебя ссд? вы заметили что-нибудь необычное в мониторинге диска или процессора?   -  person Michael Hunger    schedule 04.02.2016
comment
какую версию вы используете?   -  person Michael Hunger    schedule 04.02.2016
comment
можете ли вы поделиться кодом, который вы используете, обычно транзакционная конечная точка в Neo4j 2.2+ работает довольно быстро, см.: для 12 потоков: gist.github.com/jexp/b0a78c4681c8c9f8189f можно делать до 500 тыс. записей/с   -  person Michael Hunger    schedule 04.02.2016
comment
Версия Neo4j 2.3.2. Вышеприведенные результаты относятся к однопоточному клиенту, большому количеству оперативной памяти (xmx=10g), процессор в порядке. Я не уверен насчет поддержки активности, я проверю... Код здесь: codeshare.io/o2yCh   -  person rohrl    schedule 05.02.2016
comment
Я использую клиент Jersey REST, где по умолчанию включена поддержка активности.   -  person rohrl    schedule 05.02.2016


Ответы (1)


У меня есть ряд мыслей/вопросов, которые не очень хорошо вписываются в комментарий;)

  • Какую версию Neo4j вы используете? 2.3 представил некоторые вещи, которые могут помочь

  • Когда вы говорите, что у вас есть индекс, вы имеете в виду новый стиль, а не старые индексы? Более новые индексы создаются с помощью CREATE INDEX ON :V(guid) и применяются к комбинации метки и свойства. Вы можете попробовать свои запросы в веб-консоли с префиксом PROFILE, чтобы увидеть, попадает ли запрос в индекс и где он может быть медленным.

  • Если у вас есть данные в формате CSV, вы можете изучить предложение LOAD CSV в Cypher. Это также пакетная вещь, поэтому она может быть не такой полезной.

  • Я не думаю, что это сильно улучшит производительность, но это немного приятнее читать:

    match (a:V {guid: {a} }), (b:V {guid: {b} }) create (a)-[:label]->(b)

  • Я знаю, что сейчас это бесполезно, но в Neo4j 3.0 планируется использовать новый сжатый протокол двоичных сокетов под названием Bolt, который должен быть лучше REST. Это рассчитано на Q2

Я знаю, что многие из этих предложений, вероятно, не слишком полезны, но о них стоит подумать. Здесь также есть общедоступный чат Slack для Neo4j:

http://neo4j.com/blog/public-neo4j-users-slack-group/

Я поделюсь этим вопросом там, чтобы узнать, есть ли у кого-нибудь какие-либо идеи

ИЗМЕНИТЬ:

Макс ДеМарци передал одну из этих статей о запросах в очереди, которые могут быть полезны:

http://maxdemarzi.com/2014/07/01/scaling-concurrent-writes-in-neo4j/

Похоже, вам нужно немного написать на Java, но он выложит это за вас.

person Brian Underwood    schedule 04.02.2016
comment
Нео4дж 2.3.2. Да, индекс нового стиля. CSV неприменим. Спасибо за ссылки. - person rohrl; 05.02.2016