DB에 직접 연결해서 처리하는 경우 Driver를 로드하고 커넥션 객체를 받아와야 하는데 매번 사용자가 요청을 할 때마다 드라이버를 로드하고 커넥션 객체를 생성하여 연결하고 종료하기 때문에 매우 비효율적임
이런 문제를 해결하기 위해서 커넥션 풀을 사용
Hikari CP가 동작하는 방식
Thread가 Connection을 요청하면 Connection Pool의 각자의 방식에 따라 유휴 Connection을 찾아서 반환
Hikari CP의 경우, 이전에 사용했던 Connection이 존재하는지 확인하고, 이를 우선적으로 반환하는 특징이 있다.
가능한 Connection이 존재하지 않으면, HandOffQueue를 Polling하면서 다른 Thread가 Connection을 반납하기를 기다림
지정한 TimeOut 시간까지 대기하다가 시간이 만료되면 예외를 던진다.
최종적으로 사용한 Connection을 반납하면 Connection Pool이 Connection 사용 내역을 기록하고, HandOffQueue에 반납된 Connection을 삽입
이를 통해 HandOffQueue를 Polling하던 Thread는 Connection을 획득하고 작업을 이어나감
DB 접속 설정 객체를 미리 만들어 연결하여 메모리 상에 등록해 놓기 때문에 불필요한 작업(커넥션 생성, 삭제)이 사라지므로 클라이언트가 빠르게 DB에 접속이 가능
DB Connection 수를 제한할 수 있어서 과도한 접속으로 인한 서버 자원 고갈 방지가 가능
DB 접속 모듈을 공통화하여 DB 서버의 환경이 바뀔 경우 쉬운 유지 보수가 가능
연결이 끝난 Connection을 재사용함으로써 새로 객체를 만드는 비용을 줄일 수 있음
너무 많은 DB 접근이 발생할 경우에는 커넥션은 한정되어 있기 때문에 쓸 수 있는 커넥션이 발납될 때까지 기다려야 함
너무 많은 커넥션을 생성할 시에는 커넥션 또한 객체이므로 많은 메모리를 차지하게 되고, 프로그램의 성능을 떨어뜨리는 원인이 됨
WAS에서 커넥션 풀을 크게 설정하면 메모리 소모가 큰 대신 많은 사용자가 대기 시간이 줄어 들고, 반대로 커넥션 풀을 작게 설정하면 그 만큼 대기 시간이 길어지므로 사용량에 따라 적정량의 커넥션 객체를 생성해 두어야 함
Connection의 주체는 Thread이므로 Thread와 함께 고려해야 함
Thread Pool 크기 < Connection Pool 크기
Thread Pool에서 트랜잭션을 처리하는 Thread가 사용하는 Connection 외에 남는 Connection은 실질적으로 메모리 공간만 차지하게 된다.
Thread Pool 크기와 Connection Pool 모두 크기 증가
데이터베이스 입자에서 Connection은 Thread와 어느 정도 일치한다고 볼 수 있음
Connection이 많다는 의미는 데이터베이스 서버가 Thread를 많이 사용한다는 것을 의미하고, 이에 따라 Context Switching으로 인한 오버헤드가 더 많이 발생하기 때문에 Connection Pool을 아무리 늘리더라도 성능적인 한계가 존재
Hikari CP의 공식 문서에 의하면, 1 connections = ((core_count) * 2) + effective_spindle_count)로 정의
core_count는 현재 사용하는 서버 환경에서의 CPU 개수를 의미
effective_spindle_count는 기본적으로 DB 서버가 관리할 수 있는 동시 I/O 요청 수