우리가 개발하는 WAS와 DB는 서로 다른 시스템이다. 따라서 DB 드라이버를 사용하여 DB에 연결해야 한다.
사용자로부터 요청이 올 때마다 DB 연결을 수립하고 해제 비효율적
-> 미리 여러개의 DB 커넥션을 생성해놓고, 필요할 때마다 꺼내쓰는 방법 데이터베이스 커넥션 풀
DB 커넥션 풀을 사용하면 DB 요청이 들어올 때마다 DB 연결을 수립하고, 통신한 뒤, 닫는 과정을 거치지 않는다. DB 커넥션 풀에는 사전에 DB와 이미 연결이 수립된 다수의 커넥션들이 존재한다. 커넥션 풀 안의 커넥션들은 DB 요청이 들어올 때마다 새롭게 연결을 수립하고 닫는 대신 항상 연결을 열린 상태로 유지한다.
WAS는 DB 커넥션이 필요할 때 직접 커넥션을 생성하지 않고, 커넥션 풀 컨테이너로부터 커넥션을 하나 건네받고, 사용을 마치면 반납한다. 이렇게 DB 연결을 열고 닫는 비용을 절약한다.
가장 많이 사용되는 DB 커넥션 풀 프레임워크
스프링부트에 기본으로 내장되어 있는 JDBC DB 커넥션 풀링 프레임워크
HikariCP 팀에서 제공한 데이터페이스 커넥션 풀링 프레임워크들의 벤치마크 결과
공식문서에서의 커넥션 풀 사이즈 제안
connection = ((core_count * 2) + effective_spindle_coount)
core_count
는 CPU의 코어수 effective_spindle_count
는 DB서버가 동시 관리할 수 있는 IO 개수DBCP를 사용할 때 교착 상태(deadlock)를 주의해야 한다.
교착상태란 쓰레드가 서로의 DB connection이 반납되기만을 무한정 대기하는 상황
이 문제를 해결하기 위해서 HikariCP 팀은 아래와 같은 DBCP 최소 사이즈 공식을 제안한다.
위 공식을 적용해보자. 만약 쓰레드 최대 개수가 10개고, 동시에 필요한 커넥션수가 3개라고 해보자. 위 공식에 대입해서 계산해보면, 21이라는 결과가 나온다. 10개의 쓰레드에 모두 2개씩 커넥션을 할당하면, 1개의 커넥션이 풀에 남는다. 즉, 최소한 하나의 쓰레드는 무조건 커넥션을 3개 확보하고 작업을 처리하고, 커넥션을 반납할 수 있다. 따라서 데드락이 발생하지 않는다.
위 공식의 결과값은 어디까지나 데드락이 발생하지 않을 최소값이다. 따라서 공식 결과값에 +α가 필요하다.
그런데 그냥 DBCP 사이즈를 무식하게 크게 설정하면 데드락이고 뭐고 문제가 발생하지 않을 것 같다. 하지만 무제한으로 DB 커넥션 풀의 커넥션 개수를 늘릴 수는 없다. 커넥션도 결국 객체이기 때문에 메모리 공간을 차지하기 때문이다. 따라서 커넥션 개수와 메모리는 trade-off
관계이다. 따라서 위 공식에서 α 값을 성능 테스트를 통해 최적의 값을 찾아내야 한다.
출처 및 참고 : 데이터베이스 커넥션 풀 (Connection Pool)과 HikariCP,
Spring DB커넥션풀과 Hikari CP 알아보기,
HikariCP Dead lock에서 벗어나기 (이론편) | 우아한형제들 기술블로그
HikariCP Dead lock에서 벗어나기 (실전편) | 우아한형제들 기술블로그