Files
airflow-greenplum/docs/reference/bookings_generation_benchmark.md
T
ddadmin 6655326caa docs(all): реструктурирована документация — docs/internal/ заменён на design/, reference/, archive/, plans/
- Зачем:
  - docs/internal/ превратился в свалку: дизайн-документы, ревью, планы и справочники лежали вперемешку.
  - архивные планы были неотличимы от живых документов.
- Что:
  - docs/internal/ удалён; файлы распределены по docs/design/, docs/reference/, docs/archive/, docs/plans/, docs/assignment/.
  - educational-tasks.md убран из корня в архив (устарел).
  - обновлены все перекрёстные ссылки в AGENTS.md, TODO.md, README.md, docs/README.md и внутри design/reference/.
  - актуализированы architecture_review.md (статус DM-слоя), db_schema.md (DM-слой), TESTING.md, dag_execution_order.md, pxf_bookings.md.
  - добавлены заглушки docs/assignment/README.md и docs/plans/README.md.
- Проверка:
  - make test && make lint
  - rg 'docs/internal' --glob '!docs/archive/*' — должно быть пусто.
2026-03-10 23:02:41 +03:00

4.9 KiB
Raw Blame History

Бенчмарк генерации bookings: параллельность и тюнинг PostgreSQL

Дата: 2026-03-09 Железо: Intel Core i7-11800H @ 2.30GHz (8 ядер / 16 потоков), игровой ноутбук Среда: WSL2, Docker Desktop, PostgreSQL 16 в контейнере Данные: seed-дамп 60 дней (~500k bookings, ~180k boarding_passes, ~1.2M tickets)

Контекст

Генератор demodb (postgrespro/demodb) использует очередь событий gen.events с обработкой через process_queue(). При jobs>1 воркеры запускаются через dblink_send_query и конкурируют за очередь через SELECT ... FOR UPDATE SKIP LOCKED.

Задача: найти оптимальную конфигурацию для make bookings-generate-day (инкремент +1 день).

Методика

  • Между экспериментами: make bookings-init BOOKINGS_JOBS=N (восстановление из seed-дампа, ~18 сек).
  • Замер: time make bookings-generate-day BOOKINGS_JOBS=N.
  • Контроль: max(book_date) должен сдвинуться на +1 день.
  • Тюнинг PG: ALTER SYSTEM SET + docker compose restart bookings-db.

Параметры тюнинга PostgreSQL:

shared_buffers = 512MB      (дефолт: 128MB)
work_mem = 64MB             (дефолт: 4MB)
maintenance_work_mem = 256MB (дефолт: 64MB)
effective_cache_size = 1GB  (дефолт: 4GB)
wal_buffers = 16MB          (дефолт: -1, авто)
checkpoint_completion_target = 0.9 (дефолт: 0.9)
random_page_cost = 1.1      (дефолт: 4.0)

Результаты

# Тюнинг PG sync_commit Jobs Время vs baseline
1 нет on 1 2m 48s baseline
2 нет on 2 8m 36s 3× хуже
3 да on 1 3m 01s шум
4 да on 2 8m 42s 3× хуже
5 да off 1 2m 50s шум
6 да off 2 8m 39s 3× хуже

Повторный инкремент (прогретый кэш): 5m 03s (jobs=2), не замерялся (jobs=1).

Выводы

1. jobs=1 оптимален для инкрементов

Для генерации +1 дня параллельность через dblink контрпродуктивна:

  • Два воркера конкурируют за одну очередь gen.events через FOR UPDATE SKIP LOCKED — это row-level lock contention.
  • Overhead: dblink-соединения, синхронизация через gen.stat_jobs, polling через dblink_is_busy().
  • На WSL2 дополнительно: виртуализированный I/O не масштабируется при параллельных записях.

При генерации с нуля (make bookings-generate, десятки тысяч событий) jobs>1 может давать прирост, но не тестировалось в этом бенчмарке.

2. Тюнинг PostgreSQL не влияет

Увеличение shared_buffers в 4 раза, work_mem в 16 раз и т.д. не дало измеримого эффекта. Узкое место — не буферы и не I/O, а сама логика генератора: последовательная обработка событий с COMMIT после каждого.

3. synchronous_commit=off не влияет

Генератор делает COMMIT после каждого события (~сотни раз за день). Ожидалось, что synchronous_commit=off ускорит запись WAL. Эффект не обнаружен — вероятно, WAL-буферы и так справляются при одном потоке.

4. VACUUM-ивенты — отдельная проблема

Генератор вставляет в очередь событие VACUUM каждую неделю модельного времени. Обработчик запускает VACUUM ANALYZE всей базы через dblink_exec. При 500k+ строках это занимает минуты. Решение: DELETE FROM gen.events WHERE type = 'VACUUM' перед continue() в инкрементальных скриптах.

Итоговая конфигурация

BOOKINGS_JOBS=1         # синхронно, без dblink — ~3 мин на +1 день
BOOKINGS_INIT_DAYS=60   # seed-дамп покрывает ~34 дня бронирований + boarding_passes

Тюнинг PostgreSQL не требуется для текущих объёмов данных.