Бенчмарки Go: SQL и RESP

Обзор · Node.js · Go и RESP

Go 1.27.1 с pgx 5.11.0 и клиентом RESP2 из стандартной библиотеки; GOMAXPROCS=8. Машина и методика измерений.

Измерено 15 сентября 2026 года со сборкой расширения f03ed22. Клиент Go работает внутри виртуальной машины Linux в отдельном контейнере, разделяющем сетевое пространство имён с PostgreSQL. CPU и память клиента не входят в счётчики ресурсов сервера. RESP использует восемь воркеров, бюджет кэша/буфера 1 ГиБ и ограничение 512 клиентов.

Медиана запросов/с, три выборки по пять секунд для каждого случая:

Ключей/запрос Соединения Подготовленный SQL SQL mget RESP MGET
1 64 277,088 211,251 722,133
1 256 253,790 186,296 839,678
64 64 26,459 38,122 38,877
64 256 27,615 43,647 52,774

SQL с 64 ключами давал от 19 до 28 тысяч запросов/с при перезапусках сервера, несмотря на одинаковые данные, настройки и планы индексов. В таблице приведён более быстрый повторный запуск; причина различий пока не установлена. Все 129 выборок включают оба запуска, точные ревизии исходников, хэши бинарных файлов и планы запросов.

В выборках чтения только из кэша было 100% попаданий, без ошибок и отказов из-за лимита соединений. Нагрузочный стенд проверяет запас соединений SQL и RESP. Отдельный зонд с 256 соединениями, 64 ключами и 12 потоками Go не улучшил RESP; SQL mget получил выигрыш 6% по сравнению с восемью потоками.

Ресурсы сервера

При 256 соединениях, медианы тех же выборок:

Ключей/запрос Путь Ядра CPU клиента Ядра CPU сервера (% ВМ) мкс сервера/запрос Пиковая выборка МиБ
1 SQL 3.97 8.94 (63.9%) 36.3 679.8
1 SQL mget 3.36 9.93 (70.9%) 54.4 684.2
1 RESP MGET 5.98 6.11 (43.7%) 7.8 263.7
64 SQL 3.72 9.45 (67.5%) 348.3 689.8
64 SQL mget 5.12 4.99 (35.6%) 116.0 707.7
64 RESP MGET 5.76 4.97 (35.5%) 95.8 266.7

Клиент Go на macOS

Через опубликованные Docker-порты, при 64 соединениях; медианы трёх пятисекундных выборок, в запросах/с:

Ключей/запрос, 64 соединения Подготовленный SQL SQL mget RESP MGET
1 49,194 48,010 52,426
64 14,324 15,751 16,240

Случаи ВМ и хоста отличаются и ОС клиента, и сетевым маршрутом. Поэтому результаты через порт хоста не позволяют выделить предел пропускной способности PostgreSQL. У RESP также другой контракт сеанса: воркеры используют настроенную роль базы данных и не наследуют SQL-транзакцию или снимок вызывающего сеанса. См. справочник RESP.

Воспроизведение

Запустите бенчмарк Go

Из корня репозитория, с Docker, Node.js 20+ и Go 1.25+:

./examples/benchmark.sh go > go.json

Скрипт собирает временный сервер PostgreSQL и клиент Go, трижды запускает каждый случай, записывает ресурсы сервера и затем удаляет контейнеры. Клиент работает в ВМ Docker в отдельной cgroup от PostgreSQL. Текущие значения по умолчанию: 4/64/256 соединений, 1/16/64 ключей и пять секунд на выборку. Используйте all, чтобы запустить Node.js и Go на одном сервере с общей матрицей. Для воспроизведения записанного запуска используйте ревизии из JSON измерений.

Необязательные переопределения: CONNECTIONS, BATCHES, REPEATS, DURATION_SECONDS и GOMAXPROCS. В JSON записывается ID сборки работающего расширения.

Обновлено .