데이터베이스

Connection Pooling (데이터베이스 연결 풀) 에 대해 알아보겠습니다.

forward error correction Circle 2025. 12. 29. 08:22
반응형

Ⅰ. Connection Pooling (데이터베이스 연결 풀) 이란?

 데이터베이스 연결을 미리 생성하여 풀(pool)에 저장하고, 애플리케이션의 요청이 있을 때 풀에서 기존 연결을 빌려주는 방식으로, 연결 생성/종료 비용을 절감하고 데이터베이스 성능을 극대화하는 기술입니다

Ⅱ. Connection Pooling (데이터베이스 연결 풀) 목적

 ⅰ. 데이터베이스 연결 생성/종료 오버헤드 제거

 ⅱ. 동시 요청 처리 성능 향상

 ⅲ. 서버 리소스(CPU·메모리) 효율화

 ⅳ. 애플리케이션 응답 속도 개선

 ⅴ. DB 연결 수 초과로 인한 장애 예방

 Ⅲ. Connection Pooling (데이터베이스 연결 풀) 필요한 이유

ⅰ. 기존(비풀링) 방식의 문제

  전통적인 DB 연결 흐름은 다음과 같습니다.

  1) 요청 발생

    클라이언트 요청 
             ↓
    연결 생성 (TCP 3-way handshake, 인증, 준비)
             ↓
    SQL 쿼리 실행 (매우 짧은 시간)
             ↓
    연결 종료 (리소스 정리)

  2) 문제점

    연결 생성 시간: 100~500ms (쿼리 실행 시간보다 오래 걸림)

    불필요한 리소스 소비

    동시 연결 수 제한으로 병목 발생

    트래픽 증가 시 DB 장애 위험

Ⅳ. Connection Pooling (데이터베이스 연결 풀) 동작 원리

 ⅰ. 구조 개념

┌──────── Connection Pool ────────┐
 [Conn1]     [Conn2]    [Conn3] ...                 
  IN_USE   IDLE        IDLE                           
└───────────────────────────┘
            요청                   반환
           Application         Pool Manager
 

 

□ Pool Manager가 연결의 생성·할당·회수를 전담

애플리케이션은 연결 생성을 직접 하지 않음

 

 ⅱ. 주요 파라미터

항목 설명 일반 값
Min Pool Size 항상 유지할 최소 연결 수 5~10
Max Pool Size 최대 연결 수 20~100
Idle Timeout 유휴 연결 유지 시간 10분
Max Lifetime 연결 최대 생존 시간 30분
Validation 연결 유효성 검사  

 

 ⅲ . 동작 흐름 (6단계)

  Step 1: 풀 초기화
   애플리케이션 시작
           ↓
   Pool Manager가 최소/최대 설정값만큼 연결 생성 (고정 크기 풀이 성능에 유리)
           ↓
   모든 연결이 "대기(IDLE)" 상태로 설정

 

 Step 2: 연결 요청
  클라이언트 요청 발생
           ↓
  Pool Manager에 연결 요청
           ↓
  대기 중인 연결이 있는가?
   ├─ YES → Step 3로 진행
   └─ NO → Step 4로 진행

 

 Step 3: 기존 연결 할당
  대기 중인 연결을 "사용중(IN_USE)"으로 변경
          ↓
  연결 상태 검증 (최신 JDBC 드라이버는 내장 isValid() 사용)
          ↓
  유효하면 애플리케이션에 반환
         ↓
  쿼리 실행 (수 ms ~ 수 초)

 

 Step 4: 새로운 연결 생성
  Max Pool Size에 도달했는가? (Min/Max가 같은 고정 풀에서는 거의 항상 NO)
  ├─ YES → 풀에 연결이 반환될 때까지 대기 (타임아웃 발생 가능)
  └─ NO → (동적 풀일 경우) 새 연결 생성 (인증, 준비 포함)
  → Step 3로 진행 

 

Step 5: 연결 반환
  쿼리 작업 완료
           ↓
 애플리케이션이 연결 반환 요청
           ↓
 Pool Manager가 "대기(IDLE)" 상태로 변경
           ↓
 연결 재사용 가능 상태 유지

 

Step 6: 연결 정리
  정기적 검사 (예: 1초마다)
           ↓
  Idle Timeout 초과한 연결 확인
           ↓
  불필요한 연결 Close (동적 풀에서만 해당)
           ↓
  장시간 미사용 연결도 재검증 

Ⅴ. Connection Pooling (데이터베이스 연결 풀) 특징

구분 설명
성능 응답 속도 10~100배 향상
효율성 소수 연결로 대량 트래픽 처리
안정성 Max Connection 초과 방지
자동화 재연결·정리 자동 수행
확장성 트래픽에 따른 유연한 조정
모니터링 활성·대기·대기시간 가시화
분리 구성 읽기/쓰기, 서비스별 풀 분리

Ⅵ.  Connection Pooling (데이터베이스 연결 풀)  장·단점

 ⅰ. Connection Pooling (데이터베이스 연결 풀) 장점

항목 설명
응답 시간 대폭 개선 기존 대비 10~100배 빠른 응답 (100~500ms → 1~5ms)
동시성 제한된 DB 연결로 수천 개 동시 요청 처리
리소스 최소화 CPU, 메모리 사용 최소화로 인프라 비용 감소
안정성 "Max Connections 초과" 오류 방지
자동정리 좀비 연결 자동 감지 및 제거
가용성 DB 장애 시 자동 재연결
캐싱 효과 연결 상태(세션 변수, 트랜잭션) 유지 DB 장애 시 자동 재연결로 가용성 향상
모니터링 용이 풀 상태 가시화로 병목 진단 간편

 ⅱ. Connection Pooling (데이터베이스 연결 풀) 단점 및 대응 방법

항목 설명 대응 방법
초기 오버헤드 시작 시 연결 생성 Warm-up 시간 예약
메모리 사용 Min Pool Size * 연결당 메모리 적절한 Min 값 설정
설정 복잡성 최적의 파라미터 찾기 어려움 부하 테스트로 조정
연결 누수 반환 안된 연결이 쌓임 Leak Detection 활성화
네트워크 지연 풀의 연결도 네트워크 지연 영향 지역별 풀 구성
DB 설정 불일치 Max Connection 설정 충돌 가능 DB와 어플리케이션 동기화

Ⅶ. Connection Pooling (데이터베이스 연결 풀)  구현 예시

 ⅰ. Java (HikariCP)

1. Java (HikariCP) 사용 이유
  1) 가장 빠르고 표준적인 풀
  2) Spring Boot 기본 채택

2. 설정 방법
# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.auto-commit=true

3. 동작 예시
# 1. 풀에서 연결 획득 (기존 연결 재사용)
DataSource dataSource = DriverManager.getDataSource();
Connection conn = dataSource.getConnection(); // 약 1ms

# 2. 쿼리 실행
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users WHERE id = 1");

# 3. 연결 반환 (Close 호출 시 풀로 반환)
conn.close(); // 연결이 종료되지 않고 풀로 돌아감

 ⅱ. Python (SQLAlchemy)

1. Python (SQLAlchemy) 사용 이유
   1) QueuePool 기반
   2) pool_pre_ping 필수

2. 설정 방법
 from sqlalchemy import create_engine, event
from sqlalchemy.pool import QueuePool

# 연결 풀 설정
engine = create_engine(
    'mysql+pymysql://root:password@localhost/mydb',
    poolclass=QueuePool,
    pool_size=20,           # 항상 유지할 연결 수
    max_overflow=10,        # Max Pool Size = pool_size + max_overflow
    pool_recycle=3600,      # 1시간마다 연결 재생성 (MySQL timeout 방지)
    pool_pre_ping=True      # 연결 사용 전 검증
)

3. 동작 예시
# 쿼리 실행
with engine.connect() as connection:
    result = connection.execute("SELECT * FROM users")

Ⅷ. Connection Pooling (데이터베이스 연결 풀) 성능 비교

항목 풀(Pool) 없음 풀(Pool) 사용
평균 응답 580 ms 12 ms
메모리 800 MB 120 MB
CPU 85% 15%
최대 대기 2500 ms 50 ms

 

반응형