Database

[Database] DB Connection Pool (DBCP) 개념 및 설정 가이드

mxruhxn 2024. 10. 7. 01:06
728x90
반응형

DBCP란?

DBCP를 쓰지 않을 경우 문제점

  • TCP 기반으로 동작하다보니 매번 open / close connection에서 많은 비용 발생..
  • 서비스 성능에 좋지 않다

DBCP 개념과 원리

  • connection을 서버를 띄울 때 미리 여러개 생성해둔다.
  • 그리고 이러한 connection을 필요할 때마다 새로 생성하는 것이 아니라 기존에 맺어둔 connection을 가져와서 쓰는 방식이다.
  • close connection을 하면 연결을 끊어버리는 것이 아니라 connection pool에 반환한다.
  • 이때의 connection pool을 DBCP라고 한다.

열고 닫는 시간 절약

DBCP 설정 방법

DB connection은 backend server와 DB 서버 사이의 연결을 의미하기 때문에 백엔드 서버와 DB 서버 각각에서의 설정(configuration) 방법을 잘 알고 있어야 한다

DB 서버 설정(MySQL 기준)

    • max_connections
      • client와 맺을 수 있는 최대 connection 수
      • 이를 적절하게 설정해줘야 서버를 늘린다거나, DBCP의 connection 수를 늘린다할지라도 문제가 발생하지 않을 수 있음
      • 만약 max_connections 수가 4, DBCP의 최대 connection 수가 4라면? -> 백엔드 서버 인스턴스가 여러개일 경우 문제가 발생할 것..
    • wait_timeout
      • connection이 inactive할 때(idle 상태) 다시 요청이 오기까지 얼마의 시간을 기다린 뒤에 close할 것인지를 결정
      • 시간 내에 요청이 도착하면 0으로 초기화
      • 다음과 같은 비정상적인 conneciton 상태가 있을 수 있다.
        • 비정상적인 connection 종료
        • connection 다 쓰고 반환이 안됨
        • 네트워크 단절
        • => 이러한 상태들은 비정상적이지만, DB 입장에서는 여전히 connection이 정상적으로 연결되어 있다고 생각할 것.. 하염없이 기다릴 것이고 계속 리소스 점유해서 안 좋은 영향 줄것
        • => wat_timeout 설정하면, 마지막으로 요청을 받은 시점을 기준으로 설정된 wait_timeout만큼 기다려주고, 아무 요청이 오지 않는다면 해당 connection을 종료함.

Backend Server 설정(HikariCP 기준)

  • minimumIdle
    • pool에서 유지하는 최소한의 idle connection 수
      • idle: 어떤 요청이 올 때까지 대기하고 있는 connection
    • idle connection 수가 minimumIdle보다 작고, 전체 connection 수도 maximumPoolSize보다 작다면, 신속하게 추가로 connection을 만든다
    • 기본 값은 maximumPoolSize와 동일(= pool size 고정) ← 권장 사항임
  • maximumPoolSize
    • pool이 가질 수 있는 최대 connection 수
    • idle과 active(in-use) connection 합쳐서 최대 수 (idle + active = maximumPoolSize)
      maximumPoolSizeminimumIdle보다 우선순위가 높다!
  • maxLifetime
    • pool에서 connection의 최대 수명
    • maxLifetime을 넘기면 idle일 경우 pool에서 바로 제거, active인 경우 pool로 반환된 후 제거
      • 제거하더라도, minimumIdle의 수를 맞추기 위해 다시 새로운 connection 생성할 것
    • pool로 반환이 안되면 maxLifetime이 동작하지 않으므로 pool로 반환을 잘 시켜주는 것이 중요!!
    • DB의 connection time limit(mysql에서는 wait_timeout)보다 몇 초 짧게 설정해야 함!
  • connectionTimeout
    • pool에서 connection을 받기 위한 최대 대기 시간
    • 트래픽이 몰려서 connection이 모두 사용 중인 상황이라면 새로운 요청들은 connection을 받기 위해 계속 기다릴 것. 하지만, 무한정 기다릴 수 없기에 정해진 시간만큼만 기다리고 끊어주자.
    • 적절한 시간을 설정해야 함.. connectionTimeout을 길게 잡아서 timeout 직전에 connection을 얻고 처리를 해서 response를 client에게 반환하더라도, 이미 client가 기다리지 못하고 요청을 끊어 버렸을 수도 있음

적절한 connection 수를 찾기 위한 과정

  1. 모니터링 환경 구축(서버 리소스, 서버 스레드 수, DBCP 등등)
  2. 백엔드 시스템 부하 테스트
  3. Requeste Per Second(RPS)와 Avg Response Time(ART) 확인
    • 전체적인 처리량과 API 성능 확인 가능
  4. 백엔드 서버, DB 서버의 CPU, 메모리 등등 리소스 사용량 확인
    • 만약 백엔드 서버의 리소스 사용량이 크다면, 현재의 서버 수로는 버틸 수 없다는 것.. -> 서버 인스턴스 추가 필요
    • 만약 백엔드 서버가 아니라 DB 서버의 리소스 사용량이 크다면
      • secondary를 추가
      • 백엔드와 DB 사이에 cache layer를 추가
      • sharding
      • ...
    • 백엔드, DB 서버 모두 상태가 괜찮은데도 불구하고, 3번에서의 그래프가 특정 지점에서 변화가 없다면 5번으로 넘어가자
  5. Thread per Request 모델이라면, active thread 수 확인
    • Thread per Request: Request마다 thread를 할당해서 처리하는 모델
    • 이 모델의 동작 방식은, 요청을 처리하기 위한 thraed pool을 만들어 놓고, 요청이 올 때마다 thread가 하나씩 나가서 대응하여 처리하는 방식
    • 이러면 thread pool의 thraed 수가 병목 현상의 원인이 될 수도 있음..
    • thread pool 의 전체 thread 수가 5개인데, 실제 active thread 수도 5개라면 이는 thread pool count가 너무 작아서 생기는 병목 현상일 수도 있음
    • 그게 아니라면 다음 고려사항으로 넘어가자
  6. DBCP의 active connection 수 확인
    • 전체 connection 수와 active connection 수를 확인하여 비교
    • 서버의 hikariCP 설정에서 maximumPoolSize와 active connection 수가 서로 같다면, maximumPoolSize를 올려주어야 할 것.
    • 이때, 무작정 올리는 것이 아니라, 현재 내 서버의 수와 maximumPoolSize를 곱한 값이 DB서버의 max_connections 넘지 않도록 해야함. 만약 넘는다면, max_connections를 올릴 필요가 있음!
    • 이후, 다시 부하 테스트를 진행해보고 계속 조정한다.
  7. 사용할 백엔드 서버 수를 고려하여 DBCP의 max pool size 결정
    • max_connections는 어느 정도 여유분을 두는게 좋다.
    • maxx_connection보다 (백엔드 서버 수 * DBCP max size)가 작게 잡힐 수 있도록 DBCP max size를 설정해 주는 것이 좋다.
      • 일반적인 백엔드 서버들 외에도 다양한 형태의 클라이언트들이 존재할 수 있기 때문이다. (가령 테스트를 위한 서버나 개발자들이 쓰는 클라이언트 프로그램 등등)
728x90
반응형