Повышение производительности оценки команд сервера Gremlin

При вставке десятков тысяч узлов и ребер в tinkerpop с поддержкой cassandra я вижу, что практически все службы в основном простаивают, за исключением сервера Gremlin. То есть клиент, подключенный к веб-сокету и отправляющий команды в формате Gremlin, не потребляет много процессорного времени, как и Cassandra или ElasticSearch. Gremlin Server, с другой стороны, использует несколько процессоров (на довольно мощной машине с десятками ядер и сотнями гигабайт оперативной памяти).

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

Рабочая теория состоит в том, что узким местом сервера gremlin является оценка команд Gremlin (g.addV и т. Д.). Есть ли у кого-нибудь опыт получения высоких показателей загрузки с помощью плагина websocket, или мне необходимо написать собственный плагин JVM langauge, который работает с двоичными данными, чтобы избежать синтаксического анализа и оценки строк?

РЕДАКТИРОВАТЬ: сценарии представляют собой пакеты до 100 операторов вставки вершин или вставок ребер / вершин / ребер:

Вставки вершин:

graph.addVertex(label, tyParam, 'ident', vertexName, param1, val1, param2, val2 ...) ;
graph.addVertex(...) ; 
...

Для троек ребро, вершина, ребро:

edgeNode = graph.addVertex(...) ; 
g.V().has('ident',var).next().addEdge(var2,edgeNode) ;
edgeNode.addEdge(var3, g.V().has('ident',var4).next())

Идентификатор индексируется узлом, поэтому .has должен работать быстро. К сожалению, набор данных включает ребра для несуществующих источников или мест назначения, что вызывает ошибку FastNoSuchElementException. В случаях ошибки мы разделяем набор операторов пополам и повторяем скрипт как две меньшие попытки вставки. Например, сценарий с ошибкой 50 операторов вставки ребра / вершины / ребра становится двумя сценариями из 25, и этот процесс продолжается вплоть до сценария с одной вставкой e / v / e, где любой сбой игнорируется.

N.B. Я использую Titan 1.0.


person Thomas M. DuBuisson    schedule 29.08.2016    source источник
comment
Вы используете параметризованные скрипты? tinkerpop.apache.org/docs/3.0.1-incubating/ < / а>   -  person Jason Plurad    schedule 29.08.2016
comment
Да, все скрипты параметризованы.   -  person Thomas M. DuBuisson    schedule 29.08.2016
comment
вы упомянули рабочие потоки GS - какой конкретный параметр вы имеете в виду, когда говорите это?   -  person stephen mallette    schedule 30.08.2016
comment
@stephenmallette Я имел в виду параметры конфигурации threadPoolWorker и gremlinPool, не оказавшие заметного влияния. ‹4 ядра используются в любой момент времени.   -  person Thomas M. DuBuisson    schedule 30.08.2016
comment
Хм. Я ожидаю, что gremlinPool окажет влияние. Я недавно изменил значение по умолчанию на Runtime.availableProcessors () вместо жестко запрограммированного значения, которое у нас было, поскольку это иногда оставляло людей, которые ставили сервер gremlin на машины с большим количеством ядер, недостаточно загруженных, потому что они не настраивали значение по умолчанию.   -  person stephen mallette    schedule 31.08.2016
comment
@stephenmallette Не оказывая заметного влияния, я должен сказать, что увеличение количества потоков (gremlinPool) не заставляет нас потреблять более 4 ядер, и Кассандре по-прежнему скучно. Даже чрезмерное gremlinPool=260 не поможет нам преодолеть этот горб.   -  person Thomas M. DuBuisson    schedule 31.08.2016
comment
хм - каков характер скриптов, которые вы отправляете на сервер Gremlin? в основном читал? записывать? длинный пробег? краткосрочной перспективе?   -  person stephen mallette    schedule 31.08.2016
comment
@stephenmallette Я обновлю вопрос, выиграю редактирование через минуту. Сценарии представляют собой 1, 25, 50 или 100 операторов: graph.addVertex(label, tyParam, 'ident', vertexName, param1, val1, param2, val2 ...) ; graph.addVertex(...) ; ... или добавление троек edge, node, edge: edgeNode = graph.addVertex(...) ; g.V().has('ident',var).next().addEdge(var2,edgeNode) ; edgeNode.addEdge(var3, g.V().has('ident',var4).next()).   -  person Thomas M. DuBuisson    schedule 31.08.2016
comment
Стоимость оценки скрипта довольно низкая. Все затраты включены в первую оценку, после которой скомпилированный сценарий кэшируется, и будущие вызовы этого сценария должны быть на одном уровне с обычным двоичным исполнением. Согласно описанной вами модели загрузки у вас есть только 4 сценария, которые сервер gremlin когда-либо должен компилировать в первый раз (поэтому @JasonPlurad спросил о параметризации). Я предполагаю, что отдельные 1,25,50,100 скриптов, отправляемых каждый раз, идентичны даже до имени переменной - если да, то все в порядке. Вы используете драйвер java? или загрузка с не-jvm языка?   -  person stephen mallette    schedule 02.09.2016
comment
@stephenmallette Спасибо. Хотя в принципе я понимал, что параметризация скрипта предназначена для кеширования, я, похоже, не применил эти знания должным образом. Каждая addVertex команда может различаться по количеству параметров и, следовательно, быть отдельным скриптом. Например, в пакетах по 100 с двумя разными возможными счетчиками параметров для вершин это означает 2 ^ 100 возможных сценариев - кэширования не произойдет. Я могу написать быстрый ответ, или вы могли бы, если хотите, и я с радостью его приму. Остается одна загадка: почему использование памяти GS осталось неизменным - разве не должен был взорваться кеш скриптов?   -  person Thomas M. DuBuisson    schedule 03.09.2016
comment
Если вы можете настроить свои сценарии, чтобы лучше использовать параметризацию, вы должны увидеть лучшее увеличение пропускной способности. Я не уверен, почему вы не заметили увеличения использования памяти с течением времени. Я, вероятно, ожидал этого, если только вы не получали какие-то попадания в кеш где-нибудь, что позволяло вам повторно использовать некоторые запросы. Если вы используете Titan 1.0, мне интересно, использовали ли мы по умолчанию мягкие ссылки в кеше скриптов, которые теоретически предотвратили бы OutOfMemoryException - но я не могу вспомнить, было ли это так.   -  person stephen mallette    schedule 03.09.2016
comment
Если лучшая параметризация скрипта решит вашу проблему, возможно, @JasonPlurad должен написать ответ и получить признание - он вроде как назвал это с самого начала. :) если нет, то могу написать.   -  person stephen mallette    schedule 03.09.2016
comment
Я посмотрю, что я могу сделать, но если кто-то опередит меня, чтобы опубликовать твердый ответ, все будет хорошо.   -  person Jason Plurad    schedule 03.09.2016


Ответы (1)


Для наилучшей производительности в Сервер Gremlin. Без этого сервер не может эффективно использовать свой кеш сценариев, и каждый обрабатываемый сценарий требует компиляции, что обычно является одной из наиболее дорогостоящих частей запроса. Обратите внимание, что для работы кеша сценариев сценарии должны быть идентичны во всех смыслах по своему тексту, даже если они включают имена переменных. Другими словами:

g.V(var1)
g.V(var2)

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

В том случае, если невозможно сделать сценарии идентичными, было бы разумно отправлять такие сценарии с параметром запроса #jsr223.groovy.engine.keep.globals, установленным на другое значение, кроме hard (т.е. soft, weak или phantom), чтобы сервер Gremlin мог освободить память из кэш сценария по мере поступления новых сценариев.

person stephen mallette    schedule 09.09.2016