DBAtlas · 데이터베이스 운영 아틀라스

결정: 커넥션 풀링을 어떻게 구성하는가?

모든 데이터베이스 연결은 메모리와 스케줄링 비용을 수반한다. 연결 수가 통제 없이 증가하면 서버가 느려지거나 다운될 수 있다. 커넥션 풀은 소수의 영구 연결을 재사용해 이를 해결한다. 이 트리는 풀의 위치, 사용할 모드(session/transaction/statement), 적정 크기 결정을 안내하며, 서버리스 환경에서 외부 풀러가 필수인 이유를 강조한다.

애플리케이션 아키텍처는 어떻게 연결하는가?

풀링 결정은 아키텍처에서 시작한다. 단일 장기 실행 애플리케이션 프로세스(전통적 서버)인가, 다수의 독립 프로세스/인스턴스(마이크로서비스, 다수의 pod)인가, 아니면 요청마다 생성되고 사라지는 서버리스/Lambda 함수인가? 각각 다른 풀 배치가 필요하다.

  • 하나/소수의 장기 실행 애플리케이션 프로세스
  • 다수의 프로세스/인스턴스/pod가 같은 DB에 연결
  • 서버리스 / Lambda / 단기 실행 함수
  • 먼저 올바른 풀 크기 선택 방법을 알려 달라

미들웨어 풀러 모드는 어떻게 선택해야 하는가?

클라이언트가 많으면 미들웨어 풀러(PgBouncer, ProxySQL)가 DB의 연결 수를 낮게 유지한다. 그러나 풀 모드는 애플리케이션이 사용하는 기능에 따라 달라진다: 세션에 묶인 상태(prepared statement, 임시 테이블, SET, advisory lock, 세션 수준 기능)에 의존하는가, 아니면 모든 작업이 단일 트랜잭션 안에서 완료되는가?

  • 세션 상태(SET, 임시 테이블, 세션 prepared statement)에 의존함
  • 트랜잭션이 짧고 독립적이며 세션 상태를 유지하지 않음

권장: 애플리케이션 내 커넥션 풀

하나/소수의 장기 실행 프로세스에는 애플리케이션 내 풀 라이브러리(HikariCP, Go database/sql의 내장 풀, .NET connection pooling)로 대부분의 요구를 충족한다. 연결을 한 번 열고 반복해서 재사용한다.

권장: 풀 크기를 올바르게 설정

풀은 너무 작아도(요청 대기) 너무 커도 안 된다. 연결이 너무 많으면 CPU 컨텍스트 스위칭과 락 경합이 발생해 처리량이 떨어진다. 크기는 무한정 늘리는 숫자가 아니라 코어와 I/O에 기반한 작은 숫자다.

권장: Session 풀 모드

Session 모드에서는 클라이언트 연결이 세션 종료 시까지 백엔드 서버 연결에 고정된다. 세션 수준 상태(SET, 임시 테이블, advisory lock, 세션 prepared statement)가 유지되지만 연결 공유는 최소화된다.

권장: Transaction 풀 모드

Transaction 모드에서는 서버 연결이 트랜잭션 동안만 클라이언트에 할당되고 트랜잭션이 끝나면 풀로 반환된다. 따라서 수천 개의 클라이언트가 DB의 매우 적은 실제 연결로 작업할 수 있다. 대규모 환경에서 가장 일반적인 모드다.

권장: 서버리스에는 외부 풀러가 필수

서버리스/Lambda 함수는 빠르게 확장되며 각 인스턴스가 자체 연결을 연다. 인스턴스가 단기 실행이고 아무것도 공유하지 않으므로 애플리케이션 내 풀은 도움이 되지 않는다. 수백/수천 개의 인스턴스가 갑자기 생성되면 DB 연결 한도가 초과된다. 해결책은 DB 앞단의 외부 커넥션 풀이다.

DBAtlas에서 열기 →