코딩관계론

DB Connection Pool은 왜 필요할까? 본문

개발/Java

DB Connection Pool은 왜 필요할까?

개발자_티모 2024. 7. 2. 20:08
반응형

DB Connection Pool

DB Connection Pool은 웹 컨테이너(WAS)가 실행되면서 DB와 미리 connection(연결)을 해놓은 객체들을 pool에 저장해두었다가 필요한 시점에 연결이 아닌 이 풀에서 객체를 전달하는 방식을 의미한다. 이를 통해 애플리케이션의 성능을 향상시키고, 자원 관리를 효율적으로 할 수 있다.

DB Connection Pool이 필요한 이유는?

    1. 네트워크 연결 비용 감소: 네트워크를 통해 DB에 접속하게 된다. 이 네트워크는 TCP/IP 기반으로 동작하기 때문에 네트워크가 연결을 수립하기 전에 3-way handshake를 맺어야 한다. 이 과정은 추가적인 비용이 발생하며, 사용자 입장에서는 지연 시간이 생기기 때문에 애플리케이션의 사용 경험에 부정적인 영향을 미친다.
    2. 성능 향상: 매번 새로운 DB 연결을 생성하는 대신, 미리 생성된 연결을 재사용하면 연결 생성 및 해제에 드는 시간을 절약할 수 있다. 이는 특히 다수의 사용자가 동시에 접속하는 상황에서 성능을 크게 향상시킨다.
    3. 자원 관리 효율성: DB 연결은 시스템 자원을 소비한다. Connection Pool을 사용하면 필요한 만큼의 연결만 유지할 수 있으며, 과도한 연결로 인한 자원 낭비를 방지할 수 있다. 또한, 일정 수 이상의 연결을 제한하여 DB 서버에 과부하가 걸리는 것을 방지할 수 있다.

DB Connection Pool은 어떻게 작동할까?

JDBC Connection Pool인 Hikari CP가 동작하는 방식을 알아보자.

1. 커넥션 요청 처리

  • Step 1: 요청: 애플리케이션이 커넥션을 요청합니다.
  • Step 2: Concurrent Bag 확인: HikariCP는 Concurrent Bag에서 사용 가능한 커넥션을 찾습니다.
    1. Thread가 HikariCP에게 Connection 객체를 요청 HikariCP는 pool에 방문한 내역이 있는지 확인 후 있다면 당시에 전달한 Connection 객체를 우선적으로 return함
    2. 만약 해당 Connection 객체가 없다면 Concurrent Bag에서 사용 가능한 Connection 객체를 전달합니다.
    3. 만약 Connection 객체가 없다면 요청 THREAD는 handoff queue에 들어가서 대기하게 됩니다

2. 커넥션 반환 처리

  • Step 3: 커넥션 반환: 애플리케이션이 사용을 마친 커넥션을 반환합니다.
  • Step 4: HandOffQueue 확인: 반환된 커넥션이 있을 때, HikariCP는 HandOffQueue를 확인합니다.
    • 대기 중인 요청이 있다면, 반환된 커넥션을 즉시 할당합니다.
    • 대기 중인 요청이 없다면, 반환된 커넥션을 Concurrent Bag에 추가합니다.

커넥션 풀이 남아있는 경우

 

모든 요청이 비어있는 상태로 thread가 queue에서 대기하는 상태

자바에서는 어떻게 사용하는가?

DB Connection Pool은 각 벤더사마다 구현한 방법이 모두 다르다. 따라서 자바에서는 Datasource라는 인터페이스를 사용해서 Connection Pool기능을 제공해준다. Hikari CP는 최종적으로 JDBC인터페이스를 사용하기 때문에 각 벤더사의 의존성을 없앨 수 있었다.

깊게 생각해보기

Q. Thread보다 Connection Pool의 개수가 많으면?

A. 당연히 Connection pool이 손해를 보게 된다. 보통은 thread 풀 사이즈보다 Connection 풀 사이즈가 적다. 그 이유는 사용자의 모든 요청이 db의 커넥션이 필요한 것이 아니기 때문이다. 또한 쓰레드 풀 사이즈보다 많다면 놀고있는 커넥션 풀이 생기기 때문에 자원 관리 차원에서 좋지 않다.

 

Q. Connection Pool 사이즈 결정 방법은? 예를들면 사용자 요청은 1분에 한 번 들어오고, 쿼리의 처리에 소요되는 시간은 30초이다 .

  • 사용자 요청 빈도: 1분에 한 번
  • 쿼리 처리 시간: 30초

Pool Size 결정 방법

위의 조건을 토대로, Connection Pool의 사이즈를 결정하는 방법은 다음과 같습니다:

  1. 사용자 요청 분석:
    • 사용자는 1분에 한 번 요청을 보냅니다.
    • 쿼리의 결과를 가져오는 데 30초가 소요됩니다.
  2. Connection Pool 관리:
    • 사용자가 1분에 한 번 요청을 보낸다면, 하나의 요청이 처리되고 나서 다음 요청이 들어올 때까지 30초의 여유가 있습니다.
    • 즉, 한 번의 요청을 처리하는 데 필요한 시간(30초)이 지나면 Connection이 반납됩니다.
    • 따라서, 1분에 한 번씩 오는 요청을 처리하기 위해서는 단 하나의 Connection만 필요합니다.

 

HikariCP Dead lock을 피하려면 ?

pool size = Tn * (Cm - 1) + 1

  • Tn : 전체 Thread 갯수
  • Cm : 하나의 Task에서 동시에 필요한 Connection 수

중요한 점은 해당 공식으로 나온 POOL SIZE가 최적이 아니라 최소의 POOL의 개수가 된다

 

 

 

반응형