Бенчмарки Go: SQL и 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 сборки работающего
расширения.
Обновлено .