DB 커넥션 풀 크기를 늘렸는데 오히려 느려진 이유
문제 발생
트래픽이 늘면서 DB 커넥션 부족 에러가 보이자, 커넥션 풀 크기를 기존 10에서 100으로 늘렸습니다. 그런데 전체 처리량은 늘지 않고 오히려 평균 응답 시간이 나빠졌습니다.
원인 분석
"커넥션이 많을수록 동시에 더 많은 쿼리를 처리할 수 있다"는 직관은 어느 지점까지만 맞습니다. DB 서버 자체가 실제로 동시에 처리할 수 있는 작업량은 CPU 코어 수, 디스크 I/O 처리량 등 물리적인 한계로 정해져 있습니다.
애플리케이션 서버에서 커넥션을 100개로 늘려도, DB가 감당할 수 있는 동시 작업이 예를 들어 20개 정도라면 나머지 80개의 요청은 DB 내부에서 락 대기, CPU 컨텍스트 스위칭, I/O 큐잉으로 대기하게 됩니다. 오히려 커넥션이 많을수록 DB 내부의 경쟁(락 경합, 캐시 스래싱)이 늘어나 전체 처리량이 떨어지는 경우가 실제로 있습니다 — PostgreSQL 커뮤니티에서 자주 인용되는 경험칙으로 "코어 수 × 2 + 유효 스핀들 수" 같은 공식이 언급되기도 하지만, 이는 절대적인 규칙이 아니라 시작점입니다.
해결 방안
- 풀 크기를 "트래픽이 늘었으니 크게"가 아니라 DB가 실제로 감당 가능한 동시 작업 수를 기준으로 정합니다. DB 서버의 CPU 코어 수, 디스크 성능, 쿼리 복잡도에 따라 적정 값이 다릅니다.
- 애플리케이션 서버가 여러 대라면, 전체 커넥션 수는 (인스턴스당 풀 크기) × (인스턴스 수)입니다 — 인스턴스를 오토스케일링으로 늘리면 전체 커넥션 수가 DB의
max_connections를 넘을 수 있으므로 이것까지 고려해야 합니다. - 커넥션 풀 앞에 PgBouncer(PostgreSQL) 같은 전용 커넥션 풀러를 두는 것도 방법입니다 — 애플리케이션 커넥션은 많이 허용하면서, 실제 DB로 가는 커넥션 수는 훨씬 적게 유지하도록 중간에서 멀티플렉싱합니다.
- 문제의 진짜 원인이 "커넥션 수 부족"이 아니라 느린 쿼리가 커넥션을 오래 붙잡고 있는 것일 수도 있습니다 — 이 경우 풀을 키우는 건 증상만 완화할 뿐이고, 느린 쿼리 자체(인덱스 누락, N+1 등)를 고치는 게 근본 해결책입니다.
- 풀 크기를 바꿀 때마다 실제 처리량(throughput)과 p95/p99 응답 시간을 함께 측정해, 어느 지점부터 늘려도 효과가 없거나 오히려 나빠지는지 실측으로 확인합니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.