Перейти к основному содержимому

Методика тестирования

На этой странице описано, как Liteset сравнивался с upstream Apache Superset 6.0.0. Цель — честное и воспроизводимое измерение: одно и то же железо, те же данные, тот же профиль нагрузки; меняется только модель конкурентности бэкенда.

Единственная переменная между каждой парой прогонов — бэкенд: Flask + Gunicorn (4 sync-воркера) против Litestar + Uvicorn (4 воркера + uvloop). СУБД, данные, сеть и генератор нагрузки идентичны.

Небольшое личное замечание от автора

Это моё первое нагрузочное тестирование такого масштаба, и оно сделано в рамках дипломной работы, а не в полноценной лаборатории бенчмаркинга. Я старался сделать методику честной и воспроизводимой, но вполне мог где-то ошибиться. Не судите строго — а если вам интересно и вы заметите ошибки или недочёты, я открыт к критике и буду рад обратной связи.

Тестовый стенд

КомпонентvCPURAMДискПримечание
ВМ бэкенда48 ГБ100 % vCPU; Flask/Gunicorn или Litestar/Uvicorn
ВМ Locust24 ГБгенератор нагрузки, та же LAN
PostgreSQL 16416 ГБ50 ГБ NVMeметаданные + аналитические данные; узкое место по IO

Хост: Dell PowerEdge R420, 2× Xeon E5-2420 v2 (2,6 ГГц), DDR3 ECC, NVMe SSD, Rocky Linux 9. Все сервисы — в Docker Compose.

PostgreSQL намеренно ограничен по ресурсам относительно объёма данных, чтобы аналитические запросы занимали 5–50 с и нагрузка была IO-bound. Тюнинг: shared_buffers = 4 ГБ, work_mem = 64 МБ, effective_cache_size = 12 ГБ, random_page_cost = 8, max_parallel_workers = 4.

Тестируемое ПО

ВариантСтек
Apache Superset 6.0.0Flask + Gunicorn, 4 синхронных воркера, таймаут 300 с
LitesetLitestar + Uvicorn, 4 воркера + uvloop, async event loop

Одинаковое число воркеров (по 4) изолирует модель конкурентности: sync-воркер обрабатывает один запрос за раз и блокируется на IO; async-воркер мультиплексирует множество корутин в одном процессе. Оба работают с одной и той же PostgreSQL без изменений схемы — superset_config.py подключается без модификации.

Набор данных

Аналитическая БД наполнена по Star Schema Benchmark (SSB) при Scale Factor 10 — ~60 млн строк в LINEORDER плюс четыре таблицы измерений (CUSTOMER, SUPPLIER, PART, DATE). SSB — стандартный аналитический бенчмарк с детерминированной генерацией (ssb-dbgen), реалистичными JOIN/агрегациями и широким использованием в академической литературе. Поверх него созданы 10 дашбордов по 6–12 чартов, реализующих четыре стандартных Query Flights SSB (Q1.1–Q4.3).

Генератор нагрузки

Нагрузка генерируется через Locust с отдельной ВМ в той же LAN для минимизации сетевых задержек.

Профили нагрузки

Сценарий 1 — Dashboard Fan-Out

Загрузка дашборда с 3–13 чартами, каждый порождает свой SQL-запрос. 200 одновременных пользователей, 15 минут. Каждый пользователь загружает случайный дашборд с паузой 3–5 с. Проверяет способность бэкенда параллельно выполнять множество IO-bound операций.

Сценарий 2 — SQL Lab Interactive Session

Дата-инженер последовательно выполняет SSB-запросы через API SQL Lab, ожидая результат. 50 одновременных пользователей, 10 минут, по 10 запросов из SSB Query Flights. Измеряет латентность при конкурентном доступе к аналитической СУБД — и отзывчивость инфраструктурных эндпоинтов параллельно с тяжёлыми запросами.

Сценарий 3 — Controlled IO Latency Sweep

Запросы к виртуальному датасету на основе pg_sleep с фиксированными задержками (10 мс, 50 мс, 100 мс, 500 мс, 1 с, 5 с). 50 одновременных пользователей, по 2 минуты на задержку. Исключает вариативность SQL, поэтому единственная переменная — модель конкурентности; наиболее наглядная демонстрация преимущества async.

Метрики

Шесть групп метрик на сценарий:

МетрикаЧто показывает
Пропускная способность (RPS)Успешные запросы в секунду (Locust)
Время ответаМедиана, P95 и P99 (Locust) — хвостовая задержка отражает очереди
Доля ошибокПроцент ответов 4xx/5xx
CPUСреднее и пиковое CPU контейнера бэкенда (docker stats)
Resident memory (RSS)Резидентный объём памяти процесса бэкенда (docker stats)
Соединения PostgreSQLАктивные соединения через pg_stat_activity — выявляет утечки

Процедура

Каждый сценарий выполняется по стандартизированной процедуре из пяти этапов:

  1. Сброс — перезапуск контейнеров бэкенда и Redis для сброса состояния.
  2. Прогрев — 60 с минимальной нагрузки, результаты отбрасываются.
  3. Основной прогон — 5 минут стабильной нагрузки при целевом числе пользователей (длительности по сценариям указаны выше).
  4. Фиксация — выгрузка CSV Locust (stats, stats_history, failures) и docker stats.
  5. Повтор — каждый сценарий выполняется 3 раза для статистически устойчивых результатов.

Сопоставимость

Оба бэкенда разворачиваются:

  • В одном Docker Compose стеке — меняется только образ бэкенда
  • С идентичными PostgreSQL, Redis и Celery — без изменений между прогонами
  • На одних и тех же фикстурах данных и дашбордов — bootstrap из одного SSB-снапшота
  • С одинаковым auth-путём — itsdangerous-подписанная session cookie выпускается один раз и переиспользуется

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

Точные Locust-скрипты, манифесты инфраструктуры и сырые CSV-результаты хранятся вместе с дипломным отчётом о тестировании. Каждый результат на странице Результаты соответствует одному из трёх сценариев выше.