o2o-negosium-original/lps/tests/test_pool_autosize.py
민헌 9c2432c818 feat(lps): process_count 기반 커넥션 풀 자동 산정 — 멀티코어 풀 오버서브스크립션 방지
connection_budget(기본 40)을 두고, 기동 시 process_count 에 맞춰
pool_size/max_overflow 를 역산: (pool+overflow)×2엔진×process_count ≤ budget.
워커를 늘려도 config 가 스스로 예산을 지켜 커넥션 고갈→요청 실패를 예방.

- config_models: MainDBConfig.connection_budget 추가
- server_configs: _autosize_pool(process_count 확정 후 산정) + _apply_pool_env_override
  (우선순위 = 명시 DB_POOL_SIZE > 자동 산정 > toml pool)
- web_main: 기동 로그에 실효 풀/총커넥션/예산 출력
- env: DB_CONNECTION_BUDGET override, docker-compose 에 knob 노출
- tests: test_pool_autosize 10케이스(예산 준수·분할비·비활성·infeasible 바닥)
- docs: operations 2-1 멀티코어/풀 섹션 + loadtest README 자동산정 표

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 23:59:05 +09:00

58 lines
2.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""커넥션 풀 자동 산정(_autosize_pool) — process_count 기준으로 예산을 넘지 않아야 한다."""
import pytest
from config.config_models import MainDBConfig
from config.server_configs import _autosize_pool
def _conns(cfg: MainDBConfig, pc: int) -> int:
# 실제 동시 커넥션 = (pool + overflow) × 2엔진(R/W) × process_count
return (cfg.pool_size + cfg.max_overflow) * 2 * pc
@pytest.mark.parametrize("pc", [1, 2, 4, 8, 16])
def test_autosize_within_budget(pc):
cfg = MainDBConfig(connection_budget=40)
_autosize_pool(cfg, pc)
assert _conns(cfg, pc) <= 40
assert cfg.pool_size >= 1
assert cfg.max_overflow >= 0
def test_autosize_uses_budget_efficiently():
# 예산을 지나치게 낭비하지 않아야(넉넉한 예산일 때 절반 이상 활용)
cfg = MainDBConfig(connection_budget=96)
_autosize_pool(cfg, 4)
assert _conns(cfg, 4) <= 96
assert _conns(cfg, 4) >= 96 // 2
def test_autosize_split_ratio():
# pool(정상) 이 overflow(버스트)보다 크거나 같게 분할
cfg = MainDBConfig(connection_budget=96)
_autosize_pool(cfg, 1)
assert cfg.pool_size >= cfg.max_overflow
def test_autosize_disabled_when_budget_zero():
# budget<=0 이면 자동 산정 끔 → toml/기본 pool 값 유지, None 반환
cfg = MainDBConfig(connection_budget=0, pool_size=10, max_overflow=20)
assert _autosize_pool(cfg, 4) is None
assert (cfg.pool_size, cfg.max_overflow) == (10, 20)
def test_autosize_returns_computed_pair():
cfg = MainDBConfig(connection_budget=40)
result = _autosize_pool(cfg, 2)
assert result == (cfg.pool_size, cfg.max_overflow)
def test_autosize_infeasible_process_count_floors_at_one():
# process_count×2 > budget 이면 예산 준수가 물리적으로 불가능(워커당 최소 1커넥션 필요).
# 이때는 pool_size=1/overflow=0(엔진당 1커넥션)까지 줄이는 게 한계 — 0 풀은 만들지 않는다.
cfg = MainDBConfig(connection_budget=40)
_autosize_pool(cfg, 64)
assert cfg.pool_size == 1
assert cfg.max_overflow == 0