Технология блокчейн

Неожиданное узкое место gRPC клиента в сетях с низкой задержкой и пути его решения

Технология блокчейн
The Surprising gRPC Client Bottleneck in Low-Latency Networks

Исследование выявляет скрытую проблему производительности gRPC клиента в высокоскоростных сетях с низкой задержкой и предлагает эффективные методы повышения пропускной способности и снижения задержек для оптимизации работы приложений на основе распределённых систем.

gRPC давно завоевал популярность среди разработчиков благодаря своей производительности и надёжности как платформа для межсервисного взаимодействия. Используемый во множестве масштабируемых распределённых систем, gRPC построен поверх протокола HTTP/2 и позволяет эффективно управлять большим числом параллельных запросов с минимальной задержкой. Однако, несмотря на эти преимущества, в определённых условиях, особенно при работе в сетях с очень низкой задержкой, был обнаружен неожиданный узкий профиль на стороне клиента gRPC, способный существенно ограничивать производительность и увеличивать время отклика приложений. В данной статье мы подробно рассмотрим суть проблемы, её причины и предложим проверенные решения, способные значительно улучшить скорость и стабильность работы gRPC клиентов в высокоскоростных средах. Основой для анализа послужил опыт команды разработчиков YDB — открытой распределённой SQL базы данных, которая применяет gRPC для общения клиентов с кластерами серверов.

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

Клиент gRPC оперирует несколькими каналами (channels), каждый из которых представляет собой долговременное соединение с сервером. При этом все вызовы удалённых процедур (RPC) по умолчанию транспортируются внутри одного TCP-соединения с использованием HTTP/2, что позволяет мультиплексировать множество потоков. Аналитики YDB отметили, что каналы, созданные с одинаковыми параметрами конфигурации, по факту используют общий TCP-сокет, что не всегда очевидно. При высокой параллельной нагрузке на клиента это ведёт к ограничению пропускной способности из-за лимита на число одновременно активных потоков HTTP/2, который по умолчанию составляет около 100. Когда этот лимит исчерпывается, следующие запросы на стороне клиента ставятся в очередь и ждут освобождения используемых потоков, что вызывает возникновение задержек.

 

В официальной документации gRPC рекомендуется два варианта обхода подобного узкого места: создавать отдельные каналы для участков приложения с высокой нагрузкой либо использовать пул каналов, каждый из которых имеет отличающиеся параметры, чтобы избежать объединения их через один TCP-сокет. Опыт YDB показал, что эти рекомендации на деле не разделены жёстко, а вместе представляют комплексный подход к решению проблемы. Проверка гипотезы осуществлялась с помощью собственного микро-бенчмарка — простого пинга на базе gRPC, написанного на C++. Этот тест состоял из клиентской и серверной части, запускаемых на разных физических машинах, соединённых 50 Гбит/с сетью с минимальными задержками в несколько десятков микросекунд. Такая среда идеальна для выявления внутренних узких мест клиентов, поскольку сетевые задержки минимальны и не искажают результаты.

 

Результаты показали явное отставание от теоретической линейной масштабируемости: при увеличении числа одновременных запросов производительность росла, но гораздо медленнее ожидаемой и с ростом количества параллельных запросов медианные и пиковые задержки значительно увеличивались. Анализ сетевого трафика с помощью tcpdump и Wireshark позволил исключить сетевые проблемы: не было обнаружено задержек из-за перегрузки каналов или механизмов TCP, таких как отложенные подтверждения или влияние агрегации Nagle. Главным источником дополнительной задержки оказался клиент gRPC, точнее внутренняя его логика, связанная с тем, что весь трафик от параллельных воркеров клиента мультиплексировался по одному TCP-соединению. После обработки сервером очередного пакетного ответа по всем потокам наблюдалась пауза порядка 150-200 мкс, прежде чем клиент инициировал следующий раунд запросов. Несмотря на минимализм теста и отсутствие нагрузки на саму бизнес-логику, этот промежуток оказывался доминирующей причиной роста латентности.

 

Эксперименты с созданием отдельных каналов для каждого клиента подтверждали, что если каналы создаются с одинаковыми параметрами, то по-прежнему используется общий TCP-сокет, и это не улучшает ситуацию. Зато при добавлении пользовательских аргументов к каждому каналу, заставляющих gRPC откладывать обмен по отдельным TCP-соединениям, производительность значительно выросла. Аналогично включение параметра GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, отвечающего за изоляцию каналов, эффективно устраняло проблему задействованности единственного соединения и замедления. Переход на многопоточный клиент с наборами независимых каналов по сути решает узкое место, позволяя параллельно обслуживать сотни потоков без блокировок и очередей на уровне соединений HTTP/2. Оптимизация приводит к росту пропускной способности примерно в 6 раз по сравнению с одно соединением и значительно снижает задержки при увеличении числа параллельных запросов.

Интересно, что в сетях с задержкой порядка нескольких миллисекунд подобные улучшения имеют меньшее значение, поскольку сетевая инерция доминирует на уровне клиент-серверного раунда. Значительный выигрыш достигается именно в условиях сверхбыстрых соединений с минимальным RTT. Резюмируя, выявленное узкое место gRPC клиента связано с особенностями мультиплексирования HTTP/2 при использовании единственного TCP-соединения, ограничением на количество параллельных потоков и внутренней организацией каналов в gRPC. Для его устранения эффективным решением является создание наборов каналов с уникальными параметрами, что позволяет задействовать несколько TCP-соединений и уменьшить конкуренцию за системные ресурсы. Это открытие очень важно для всех, кто строит производительные распределённые приложения с использованием gRPC в условиях высокоскоростных инфраструктур.

Автоматическая торговля на криптовалютных биржах

Далее
Lessons from scaling PostgreSQL queues to 100k events per second
Пятница, 31 Октябрь 2025 Как масштабировать Postgres очереди до 100 тысяч событий в секунду: опыт и уроки

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

Show HN: Self-updating MCP server for official pip, uv, poetry and conda docs
Пятница, 31 Октябрь 2025 Самообновляющийся MCP сервер для актуальной документации pip, uv, poetry и conda: инновационный помощник для разработчиков Python

В современном мире разработки программного обеспечения своевременный доступ к актуальной документации имеет ключевое значение для быстрого и качественного выполнения задач. Эффективное управление зависимостями и пакетами в Python стало проще благодаря новому самообновляющемуся MCP серверу, который обеспечивает автоматическое обновление и точное кросс-ссылание на официальные документы популярных менеджеров пакетов pip, conda, poetry, uv, pixi и pdm.

Show HN: Bskysrch – An Advanced Search for Bluesky
Пятница, 31 Октябрь 2025 Bskysrch: мощный инструмент для расширенного поиска в Bluesky

Подробное исследование возможностей Bskysrch — современной утилиты, которая позволяет пользователям эффективно искать публикации в социальной сети Bluesky по разнообразным критериям и улучшает взаимодействие с платформой.

California Forever changes its plans from a startup city to a startup Foundry
Пятница, 31 Октябрь 2025 California Forever: от амбиций создать новый город до технологического индустриального центра

История эволюции проекта California Forever, который изменил свои планы с создания нового города в Солано Каунти на разработку крупного промышленного технопарка Solano Foundry, объединяющего передовые технологии и производство в Калифорнии.

Simulate Harsh User Review for Claude code
Пятница, 31 Октябрь 2025 Жёсткая пользовательская рецензия на код Claude: важный инструмент для повышения качества разработки

Понимание необходимости критики в программировании позволяет разработчикам избегать ошибок и совершенствовать код. В статье рассматривается уникальный подход с использованием имитации жёстких пользовательских отзывов для AI и описывается, как этот метод способствует дисциплине и росту качества разработки.

A new study just upended AI safety
Пятница, 31 Октябрь 2025 Новый прорыв в безопасности ИИ: как скрытое обучение меняет правила игры

Исследование раскрывает неожиданные риски при обучении искусственного интеллекта на синтетических данных и ставит под вопрос текущие методы обеспечения безопасности ИИ. Углубленное понимание феномена скрытого обучения открывает новые вызовы и возможности для создания более надежных моделей.

Show HN: Geo Calculation Toolkit API
Пятница, 31 Октябрь 2025 Geo Calculation Toolkit API: Современное решение для геопространственных вычислений

Подробный обзор функционала Geo Calculation Toolkit API — мощного инструмента для работы с географическими координатами и пространственными данными, востребованного в различных сферах от картографии до логистики.