Почему сервер Gremlin / JanusGraph игнорирует некоторые мои запросы?

#gremlin #janusgraph #tinkerpop3 #gremlin-server #gremlinpython

Вопрос:

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

Условия для такого обращения с молчанием не ясны. Описанное поведение линейно не зависит от байтов или количества инструкций. Например, этот код будет висеть для меня вечно:

 g = traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin', 't'))
g = g.inject("")
for i in range(0, 8000):
    g = g.constant("test")
print(f"submitting traversal with length={len(g.bytecode.step_instructions)}")
result = g.next()
print(f"done, got: {result}") # this is never reached
 

Это не зависит только от количества байтов в сообщении запроса, так как количество инструкций, за пределами которых я не получаю ответа, не меняется даже при очень больших постоянных значениях вместо простого «теста». Например, ввод 7000 значений со многими абзацами Lorem Ipsum работает должным образом и возвращается через несколько миллисекунд.

Хотя это не должно иметь значения (так как я должен получать правильную ошибку, а не ничего), Я уже увеличил серверную часть maxHeaderSize maxChunkSize и maxContentLength т. Д. до смехотворно высоких цифр. Изменение формата сериализации (например, от GraphSONMessageSerializerV3d0 до GraphBinaryMessageSerializerV1 ) также не помогает.

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

Ответ №1:

Я ответил на этот вопрос в gremlin-пользователи, не понимающие, что его также задавали здесь, в StackOverflow. Для полноты картины я продублирую свой ответ здесь.

Проблема меньше связана с длиной байтов и строк и больше с длиной цепочки обхода (т. Е. Количеством шагов в вашем обходе). В конечном итоге вы достигнете ограничения JVM на размер стека на сервере. Вы можете увеличить размер стека в jvm, изменив размер -Xss значения, которое должно позволить вам увеличить длину обхода. Это, скорее всего, приведет к необходимости пересмотреть другие настройки JVM, такие как -Xmx и, возможно, параметры сборки мусора.

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

Комментарии:

1. Спасибо за предложение! Я уже проверил размер и использование кучи, но забыл упомянуть об этом в своем посте. Я запускаю это с кучей 16 ГБ на узле Kubernetes объемом 32 ГБ с большой вычислительной мощностью. Я вообще не вижу никаких всплесков использования, там полно всего лишнего. Я попробую увеличить размер стека.

2. Увеличение размера стека помогло — отлично. Я предварительно отмечу это как ответ, так как, хотя это устраняет проблему (спасибо!), мы не выяснили, как обнаружить это в производстве. Как я узнаю, что это проблема со стеком, а не просто тайм-аут, если сервер не отвечает? Как я могу поддерживать низкое давление в стеке при длительных обходах? Глядя на источник, кажется, что пакетирование частей обхода в Sideffect может помочь, но я недостаточно знаю о внутренней работе сервера Janus/Gremlin. Или, может быть, это разбор запросов, который накапливается в стеке..

3. я не экспериментировал со sideEffect() step, чтобы узнать, помогает ли это, но на самом деле это звучит так, как будто это может быть. если ваш вариант использования позволяет это, то, возможно, это путь, по которому следует следовать. лично я бы предпочел перестроиться, чтобы избежать длительного обхода и, возможно, даже снизить производительность, чтобы не подползать слишком близко к пределам стека.

4. если у вас должна быть длительная одиночная транзакция, которая затрагивает так много вещей, я думаю, я бы рассмотрел возможность использования сеанса и отправки нескольких запросов на него. сеансы транзакции получают лучшую поддержку в версии 3.5.0, поэтому я думаю, что буду использовать сценарии в версии 3.4.x для этого конкретного случая использования, пока строка 3.5.x не получит широкую поддержку — issues.apache.org/jira/browse/TINKERPOP-2537

5. примерно через 2 недели, если все пойдет по плану. вам нужно следить за списком рассылки разработчиков, если вы хотите быть в курсе обсуждений выпуска: lists.apache.org/list.html?dev@tinkerpop.apache.org