PostgreSQL — хранилище игровых данных: профили игроков, инвентарь, достижения, таблицы лидеров. На сервере с 256 GB RAM дефолтные настройки PostgreSQL были преступно малы:
# Дефолтные значения PostgreSQL 16 (Ubuntu)
SHOW shared_buffers; -- 128MB
SHOW work_mem; -- 4MB
SHOW effective_cache_size; -- 4GB
SHOW max_connections; -- 100
# Оптимизированные настройки для 256 GB RAM, NVMe SSD, 64 CPU
# /etc/postgresql/16/main/conf.d/performance.conf
# ── Память ──
shared_buffers = 64GB # 25% RAM
effective_cache_size = 192GB # 75% RAM (подсказка планировщику)
work_mem = 512MB # Для сортировок и хеш-таблиц
maintenance_work_mem = 4GB # Для VACUUM, CREATE INDEX
huge_pages = try # Transparent Huge Pages для shared_buffers
# ── WAL ──
wal_buffers = 256MB # 1/256 от shared_buffers
max_wal_size = 8GB
min_wal_size = 2GB
wal_compression = zstd # Сжатие WAL (PG16+)
checkpoint_completion_target = 0.9
# ── Параллелизм ──
max_worker_processes = 32
max_parallel_workers_per_gather = 8
max_parallel_workers = 32
max_parallel_maintenance_workers = 4
# ── IO для NVMe SSD ──
random_page_cost = 1.1 # Дефолт 4.0 для HDD!
effective_io_concurrency = 200 # Дефолт 1
seq_page_cost = 1.0
# ── Соединения ──
max_connections = 200 # Небольшое число! PgBouncer впереди
# ── Логирование медленных запросов ──
log_min_duration_statement = 500 # Логировать запросы > 500мс
shared_preload_libraries = 'pg_stat_statements'
# Huge Pages — снижают overhead на управление памятью
# Для 64 GB shared_buffers нужно ~33000 huge pages (2MB каждая)
# Считаем количество
echo $(( (64 * 1024 + 512) / 2 )) # 32768 + запас
# /etc/sysctl.d/99-hugepages.conf
vm.nr_hugepages = 33000
sysctl -p /etc/sysctl.d/99-hugepages.conf
grep Huge /proc/meminfo
# HugePages_Total: 33000
# HugePages_Free: 33000
# Hugepagesize: 2048 kB
PgBouncer — обязателен для игрового сервера. Каждый Go-процесс может открыть сотни соединений при всплеске. Без пулинга PostgreSQL упадёт:
# /etc/pgbouncer/pgbouncer.ini
[databases]
gamedb = host=127.0.0.1 port=5432 dbname=gamedb
[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 6432
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt
# Transaction pooling — идеально для коротких игровых запросов
pool_mode = transaction
# Лимиты
max_client_conn = 10000 # Максимум от приложения
default_pool_size = 50 # Реальных соединений к PG
min_pool_size = 10
reserve_pool_size = 10
reserve_pool_timeout = 3
# Таймауты
server_idle_timeout = 300
query_timeout = 10 # Игровые запросы должны быть быстрыми
client_idle_timeout = 600
# Логирование
log_connections = 0
log_disconnections = 0
stats_period = 60
Результат: Go-бэкенд подключается к PgBouncer на порту 6432, PgBouncer поддерживает 50 реальных соединений к PostgreSQL, обслуживая до 10 000 клиентских соединений через переиспользование.
Оставить комментарий