DB Connection Pooling으로 커넥션 부하 줄이기 (pgBouncer)

DB 커넥션 생성/해제는 비용이 많이 드는 작업으로, 트래픽 증가 시 응답 지연과 서버 자원 고갈 발생. pgBouncer를 통한 커넥션 풀링으로 미리 생성된 커넥션을 재사용하여 성능 향상과 안정성 확보

커넥션 풀링이 필요한 이유

  • TCP/IP 핸드셰이크, PostgreSQL 인증, 프로세스 생성 등으로 인한 오버헤드

  • 트래픽 급증 시 응답 시간 지연, 서버 자원 고갈, 메모리 부족 문제 발생

  • max_connections 한도 초과 시 새로운 요청 실패

pgBouncer 풀링 모드

모드
특징
Django 호환성
사용 권장

Session Pooling

클라이언트 연결 종료까지 동일 커넥션 유지

모든 PostgreSQL 기능 사용 가능

Django 기본 동작과 유사, 가장 안전

Transaction Pooling

트랜잭션 단위로 커넥션 할당/반환

세션 기반 기능 사용 불가

Stateless API 서버에 최적

Statement Pooling

SQL 구문 단위로 커넥션 할당

다중 구문 트랜잭션 불가

Django/DRF 비호환, 사용 금지

Django 적용 설정

pgBouncer 설정 (/etc/pgbouncer/pgbouncer.ini)

[databases]
myproject = host=127.0.0.1 port=5432 dbname=myproject_db

[pgbouncer]
listen_port = 6432
pool_mode = session
default_pool_size = 20
max_client_conn = 500

Django settings.py 변경

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'HOST': '127.0.0.1',     # pgBouncer 서버 주소
        'PORT': '6432',          # pgBouncer 포트
        'NAME': 'myproject',     # pgbouncer.ini의 가상 DB 이름
        'CONN_MAX_AGE': 0,       # Django 영구 커넥션 비활성화
    }
}

운영 시 주의사항

  • 모니터링 필수: SHOW POOLS, SHOW CLIENTS 명령으로 상태 확인

  • default_pool_size 튜닝: CPU 코어 수의 2~4배에서 시작하여 점진적 조정

  • 시작은 Session 모드: 안정성 확보 후 Transaction 모드 고려

Last updated