본문 바로가기
실전 프로젝트/프로젝트 과정

실전 프로젝트 22 - 커넥션풀

by 구너드 2023. 8. 31.

커넥션풀

데이터베이스 연결을 캐시로 유지하여 필요할 때마다 새로운 연결을 열거나 닫는 대신 재사용할 수 있도록 연결을 유지한채 존재하는 대기풀

 

프로그램이 데이터베이스와 상호작용해야 할 때, 일반적으로 데이터베이스 서버에 연결을 설정한다. 이 과정은 DB 서버와 3 way handshake와 같은 네트워크 통신때문에 비교적 시간이 많이 걸리고 자원을 소비하게 된다. 동시에 여러 클라이언트나 프로세스가 데이터베이스에 접근해야 하는 경우, 각 요청마다 새로운 연결을 설정하는 것은 비효율적이며 느릴 수 있다.

커넥션 풀은 이 문제를 해결하기 위해 메모리에 이미 설정된 데이터베이스 연결의 모아둔다. 클라이언트나 프로세스가 데이터베이스에 연결을 요청하면, 풀은 사용 가능한 미사용 연결이 있는지 확인하고, 만약 해당 연결이 존재한다면 클라이언트에게 제공한다. 클라이언트가 연결을 사용한 후에는 이를 닫는 대신 풀에 반환한다. 이러한 연결 재사용은 데이터베이스와 자주 상호작용해야 하는 애플리케이션의 성능을 크게 향상시킬 수 있다


이번 프로젝트에서 경매 동시성을 제어하기 위해 비관적 락을 걸어두고 동시에 많은 요청을 보냈을 때 일부 요청들은 커넥션 풀 타임아웃에러가 발생하여 입찰 데이터가 제대로 DB에 반영되지 않는 일이 발생하였다. 이를 해결하기 위해서 디폴트로 설정되어 있는 10개의 커넥션 풀을 임의로 조정하여 증가시켜주면 되지 않을까라는 생각으로 접근했고 yml 파일에 커넥션 풀을 조정한 결과 이전과 달리 타임아웃 에러가 발생하지 않았다.

 

다만 커넥션풀을 항상 디폴트 개수보다 많은 개수만큼 유지하는 게 좋을까라는 질문에는 선뜻 그렇다고 대답을 할 수 없었는데 지금까지 배워온 것들을 기반으로 유추해보면 결국 연결을 유지하는 것도 일종의 리소스 낭비이고 오버스펙으로 커넥션풀을 늘리게 된다면 이것도 성능적인 저하를 가져올 것이라고 생각했다. 

 

어느정도의 트래픽이 예상되어 동시성을 제어하기위해 비관적락을 사용하게 될 경우 커넥션풀을 늘리는 것은 합리적인 판단이 될 수 있겠지만 이는 DB 서버의 용량과도 밀접하게 관련이 있다. DB가 동시 연결의 제한된 수를 처리하고 있다면 커넥션 풀 크기를 그 수보다 적게 설정하여 과부하를 줄이려는 노력도 필요하다.

 

정리하자면 커넥션을 사용하고 있는 주체인 쓰레드의 개수보다 커넥션풀의 크기가 크다면 남는 커넥션의 메모리 낭비가 발생하므로 적절하게 조절할 필요가 있다. MySQL 공식 레퍼런스에서는 600명의 유저를 대응하는데 15~20 개 정도의 커넥션 풀로 충분히 가용가능하다고 언급하고 있다. 추가적으로 커넥션풀의 적정 개수를 찾기 위해서 다음과 같은 공식을 사용할 수 있다

 

Pool Size = Tn x (CM - 1) +1

 

Tn - 전체 쓰레드 개수

Cm - 하나의 태스크에 동시에 필요한 커넥션 수

 

따라서 적정 커넥션 풀은 Was에서 설정한 쓰레드 풀의 쓰레드 개수와 밀접한 관련이 있으며 성능적인 테스트를 통해서 적정 쓰레드 풀을 산출하고 이를 활용한 커넥션 풀 계산이 필요할 듯 싶다.

 

프로젝트 시간 상 해당 부분에 대해서 테스트를 진행해볼 시간은 부족할 거 같은데 전체 캠프 기간이 종료되면 추가적으로 해당 테스트를 진행해보는 것으로 방향을 잡아두었다.