본문 바로가기

공부내용 정리/프로그래밍

DBCP, DataBase Connection Pool 개념 정리

커넥션풀(DBCP) ?

웹 컨테이너(WAS)가 실행되면서 DB와 미리 connection(연결)을 해놓은 객체들을 pool 에 저장해두었다가, 클라이언트 요청이 오면 connection을 빌려주고, 처리가 끝나면 실행된 상태로 다시 connection을 반납받아 pool에 저장하는 방식이다.

 

DataBase Connection is Expensive

DataBase Connection은 한번 생성하는데 많은 자원과 시간을 사용하는 작업이다.

따라서 DB에 연결하려는 요청이 있을 때마다 Connection을 생성하는 것은 비효율적이기 때문에 

커넥션풀에서 커넥션을 생성해두고, 요청이 들어올 때 마다 커넥션을 쓰고, 반납받는다.

 

커넥션 풀(DBCP)을 사용하는 이유

자바에서는 DB에 직접 연결해서 처리하는 경우 JDBC드라이버를 로드하고 커넥션 객체를 받아와야 한다.

그러면 매번 사용자가 요청할때마다 드라이버를 로드하고, 커넥션 객체를 생성하여 연결하고 종료하기 때문에 비효율적이다. 

웹어플리케이션에서는 HTTP 요청에 따라 Thread를 생성하게 되고 대부분의 비지니스 로직은 DB 서버로부터 데이터를 얻게 된다.

만약 위와같이 모든 요청에 대해 DB접속을 위한 드라이버를 로드하고 커넥션 객체를 생성하여 연결한다면 물리적으로 DB서버에 계속 접근해야 한다.

그렇기 때문에 DB 커넥션 객체를 생성하는 부분에 대한 비용과 대기시간을 줄이고, 네트워크 연결에 대한 부담을 줄이기 위해 커넥션 풀을 사용한다.

 

커넥션 풀(DBCP)의 과정

1. 웹 컨테이너(WAS)가 실행되면서 connection 객체를 미리 Pool 에 생성해둔다.

2. HTTP 요청에 따라 pool에서 connection 객체를 가져다 쓰고 반환한다.

3. 이와 같은 방식으로 물리적인 데이터베이스 connection 연결 부하를 줄이고 연결을 관리한다.

4.  pool에 미리 connection이 생성되어 있기 때문에 connection을 생성하는데 드는 요청마다 연결시간이 소비되지 않는다.

5. connection을 계속해서 재사용하기 때문에 생성되는 커넥션 수를 제한적으로 설정한다.

 

스프링부트의 인터페이스를 이용한 추상화된 커넥션 획득 

- 자바에서는 이런 문제를 해결하기 위해 javax.sql.DataSource 라는 인터페이스를 제공한다.

- DataSource는 커넥션을 획득하는 방법을 추상화하는 인터페이스이다.

- 이 인터페이스의 핵심 기능은 커넥션 조회이다.

 

정리 )

대부분의 커넥션 풀은 DataSource 인터페이스를 이미 구현해두었다. 따라서 개발자는 DBCP2 커넥션풀, HikariCP 커넥션 풀의 코드를 직접 의존하는 것이 아니라 DataSource 인터페이스에만 의존하도록 애플리케이션 로직을 작성하면 된다.

 

동시 접속자가 많으면 ?

동시 접속자가 많을 경우 pool에서 미리 생성된 커넥션을 제공하고, 없을 경우 사용자는 사용중인 커넥션이 반환될 때까지 번호순대로 대기상태로 기다린다.

WAS에서 커넥션 풀을 크게 설정하면 메모리 소모가 큰 대신 많은 사용자가 대기시간이 줄어들고, 반대로 커넥션 풀을 적게 설정하면 그 만큼 대기시간이 길어진다.

 

WAS 의 Thread 수와 Connection Pool 수의 관계

Thread 와  Connection Pool 의 수는 성능에 많은 영향을 준다.

직접적으로 메모리와 관련이 있기 때문에, 많이 사용하면  할 수록 메모리를 많이 점유하게 된다.

그렇다고 반대로 메모리를 위해 적게 지정한다면, 서버에서는 많은 요청을 처리하지 못하고 대기할 수 밖에 없다.

 

DB Connection Pool 관리를 어떻게 하면 좋을까?

가장 좋은 방법은 애플리케이션을 실제 운영할 시스템 환경에서 성능 테스트를 진행하는 것.

WAS의 Thread 개수가 DB의 Connection Pool 개수보다 많아야 하는 이유는 애플리케이션에 대한 모든 요청이 DB에 접근하는 것은 아니기 때문.

그렇기 때문에 WAS 의 Thread 는 Connection Pool 의 개수보다 여유있게 설정하는 것이 좋다.

Connection Pool은 시스템 환경에 따라 다르지만 보통 40~50개로 지정하면 Thread는 이보다 10개정도 더 지정하는 것이 바람직하다. 하지만 최적의 성능을 위해서는 실제 요청이 얼마나 들어오는지 파악하는게 중요하며 가장 좋은 방법은 앞서 말한 것처럼 성능 테스트를 통해 최적화된 값을 구하는 것이다.

 

Value Description
maxActive 동시에 사용할 수 있는 최대 커넥션 개수
maxIdle ConnectionPool에 반납할 때 최대로 유지될 수 있는 커넥션 개수
minIdle 최소한으로 유지할 커넥션 개수
initialSize 최초로 getConnection() 메소드를 통해 커넥션 풀에 채워넣을 커넥션 개수

 

참고 devdo, https://velog.io/@mooh2jj/%EC%BB%A4%EB%84%A5%EC%85%98-%ED%92%80Connection-pool%EC%9D%80-%EC%99%9C-%EC%93%B0%EB%8A%94%EA%B0%80
http://d2.naver.com/helloworld/5102792
자바 성능을 결정 짓는 코딩 습관과 튜닝 이야기