커넥션 풀
Connection Pool
DB 연결을 재사용하는 기법. 오버헤드 감소.
Connection Pool
DB 연결을 재사용하는 기법. 오버헤드 감소.
커넥션 풀(Connection Pool)은 데이터베이스 연결을 미리 생성해두고 재사용하는 기법입니다. DB 연결은 TCP 핸드셰이크, 인증, 세션 초기화 등으로 비용이 높은 작업이므로, 매 요청마다 연결을 생성하고 닫는 대신 풀에서 가져다 쓰고 반환합니다.
커넥션 풀은 최소/최대 연결 수, 유휴 연결 타임아웃, 연결 검증 등을 설정할 수 있습니다. 적절한 크기 설정이 중요한데, 너무 작으면 대기가 발생하고, 너무 크면 DB 서버에 부담이 됩니다. 일반적으로 (CPU 코어 수 * 2) + 유효 스핀들 수가 권장됩니다.
애플리케이션 레벨(HikariCP, DBCP)과 미들웨어 레벨(pgBouncer, ProxySQL)에서 구현할 수 있습니다. 서버리스 환경에서는 연결 급증 문제가 있어 PgBouncer 같은 외부 풀러나 AWS RDS Proxy를 사용하기도 합니다.
# Python - SQLAlchemy 커넥션 풀 설정
from sqlalchemy import create_engine
engine = create_engine(
'postgresql://user:password@localhost/mydb',
pool_size=10, # 기본 풀 크기
max_overflow=20, # 최대 추가 연결 수
pool_timeout=30, # 연결 대기 타임아웃 (초)
pool_recycle=1800, # 연결 재활용 주기 (초)
pool_pre_ping=True # 연결 상태 확인
)
# Java - HikariCP 설정
# application.yml
spring:
datasource:
hikari:
minimum-idle: 5
maximum-pool-size: 20
idle-timeout: 300000 # 5분
max-lifetime: 1800000 # 30분
connection-timeout: 30000 # 30초
validation-timeout: 5000
leak-detection-threshold: 60000
# Node.js - pg Pool 설정
const { Pool } = require('pg');
const pool = new Pool({
host: 'localhost',
database: 'mydb',
user: 'user',
password: 'password',
max: 20, // 최대 연결 수
idleTimeoutMillis: 30000, // 유휴 타임아웃
connectionTimeoutMillis: 10000
});
// 커넥션 사용
const client = await pool.connect();
try {
const result = await client.query('SELECT * FROM users WHERE id = $1', [userId]);
return result.rows;
} finally {
client.release(); // 풀에 반환 (닫지 않음!)
}
// Django - 커넥션 풀 설정
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'HOST': 'localhost',
'NAME': 'mydb',
'CONN_MAX_AGE': 600, # 연결 유지 시간 (초)
'CONN_HEALTH_CHECKS': True,
}
}
백엔드 개발자: 트래픽 급증할 때 "too many connections" 에러가 나요.
DBA: 커넥션 풀 max_pool_size가 몇이에요? DB의 max_connections는요?
백엔드 개발자: 풀은 서버당 50개인데, 서버가 10대라서 500개고, max_connections는 200이에요.
DBA: 그럼 당연히 초과하죠. pgBouncer로 커넥션 풀링하거나, 애플리케이션 풀 크기를 줄여야 해요.
면접관: 적절한 커넥션 풀 크기는 어떻게 정하시나요?
지원자: HikariCP 공식에서는 (CPU 코어 수 * 2) + 유효 스핀들 수를 권장합니다. SSD라면 대략 코어 수의 2~3배 정도요. 하지만 실제로는 부하 테스트로 최적값을 찾아야 합니다. 쿼리 특성에 따라 달라지거든요.
면접관: 커넥션 풀 관련해서 주의할 점은요?
지원자: 연결을 반드시 반환해야 합니다. try-finally나 using 패턴으로 누수를 방지하고, leak detection 설정으로 문제를 조기에 발견해야 합니다.
시니어: 여기 connection.close()가 finally 블록 안에 없네요.
주니어: 예외 안 나면 닫히지 않나요?
시니어: 중간에 예외 나면 연결이 반환 안 돼서 풀이 고갈됩니다. 항상 finally에서 반환하거나 with 문을 쓰세요. 커넥션 누수는 찾기 어려운 버그예요.