자바 언어·플랫폼 용어 사전
실무 사례HikariCP · 풀 크기 · 리틀의 법칙 · 큐 대기

커넥션 풀 사이징

풀을 키우면 더 느려질 수 있다. 병목은 커넥션이 아니라 DB의 실제 동시 처리 능력이다.

풀을 키우면 오히려 느려진다 — 직관을 배신하는 대표 사례.

  • 증상 — 커넥션 대기가 보여서 풀을 100 → 300 으로 올렸다

    • TPS 가 떨어지고 p99 가 나빠졌다
  • 원인 — 병목은 커넥션 개수가 아니라 DB 의 실제 동시 처리 능력이었다

    • DB 에 300개가 동시에 들어가면
      • 컨텍스트 스위치 증가
      • 락 경합 증가
      • 버퍼 캐시 경쟁 → 디스크 I/O 증가
    • DB 안에서 서로를 방해한다

대기는 어디에서 하는 편이 나은가

  • 풀에서 대기 — 순서대로 줄을 선다. DB 는 최적 부하로 계속 돈다
    • 전체 처리량이 유지되고 지연이 예측 가능하다

DB 안에서 대기 모두가 조금씩 진행하며 서로를 방해한다

  • 전체가 함께 느려진다 (호위 효과)

  • 큐를 앞단에 두는 것이 시스템 전체에는 유리하다

출발점이 되는 공식

HikariCP 문서가 인용하는 경험식 풀 크기 = (코어 수 × 2) + 유효 스핀들 수

8코어 · SSD 기준 대략 20 내외에서 시작한다 "수백" 은 거의 언제나 잘못된 값이다

리틀의 법칙으로도 확인한다 필요한 동시성 = 처리량 × 평균 응답시간

  • 1,000 TPS × 10ms = 10 — → 풀 10~20 이면 충분

데드락을 부르는 설정

한 요청이 커넥션을 2개 이상 잡는 코드가 있으면 (예: 트랜잭션 안에서 다른 데이터소스 조회)

필요한 최소 풀 크기 = 스레드 수 × (요청당 최대 커넥션 - 1) + 1

  • 이보다 작으면 모두가 두 번째 커넥션을 기다리며 멈춘다
  • 애초에 요청당 커넥션은 1개만 잡도록 설계하는 편이 낫다

반드시 함께 볼 타임아웃

  • connectionTimeout — 풀에서 기다리는 최대 시간 — 무한 대기 금지
  • maxLifetime — DB/방화벽의 유휴 종료보다 짧게 (안 그러면 죽은 커넥션을 잡는다)
  • validationTimeout · leakDetectionThreshold 누수 추적

스레드 풀과 함께 봐야 한다

웹 스레드 200 · 커넥션 풀 20 이면

  • 최대 180개가 커넥션을 기다린다

이때 대기 시간이 요청 타임아웃보다 길면

  • 클라이언트는 이미 끊었는데 서버는 계속 처리한다 → 완전한 낭비

그래서 세 값을 함께 맞춘다

  • 웹 스레드 수 · 커넥션 풀 크기 · 커넥션 대기 타임아웃

가상 스레드를 쓰면 웹 스레드 수 제한이 사라지므로 '앞단에서 자연히 걸리던 제동' 도 사라진다 → 커넥션 풀·세마포어로 명시적 제한이 필요하다

모니터링할 지표

  • active / idle / pending — pending 이 지속적으로 0 보다 크면 부족 신호
  • connection acquire 시간 p99 — 여기가 응답 지연의 원인인지 판별
  • usage 시간 (빌린 시간) — 길면 커넥션을 오래 쥐고 있다는 뜻
    • 트랜잭션 안에서 외부 API 를 부르고 있지 않은지 본다

가장 흔한 실수: 트랜잭션 안에서 HTTP 호출 커넥션을 수백 ms 씩 잡고 있어 풀이 마른다

면접 함정

  • "대기가 보이면 풀을 늘린다" → 병목이 DB면 역효과다.
  • "풀은 클수록 안전" → 부하가 몰릴 때 DB를 먼저 무너뜨린다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 실무 노하우·실제 사고 사례