
커넥션 풀에 관련된 이미지를 만들어달라고 했더니 진짜 풀장을 만들어줬다 ㅋㅋ
커넥션 풀에 대해 설명하기에 앞서 데이터베이스 커넥션이 무엇인지 살펴보자.
위와 같은 과정을 통해 데이터베이스 커넥션이 이루어지고, 사용자로부터 웹 애플리케이션에 요청이 들어올때마다 데이터베이스 연결을 수립하고 해제하는 것은 굉장히 비효율적으로 보인다.
클라이언트로서의 자바 프로그램(JSP)이 직접 DB 서버에 접근해 데이터를 액세스하는 구조이다.
자바 프로그램과 DB 서버 중간에 미들웨어 층을 둔다.
미들웨어 층한테 비즈니스 로직, 트랜잭션 처리, 리소스 관리를 전부 맡기는 구조이다.
데이터베이스 커넥션 풀(Database Connection Pool)은 데이터베이스와의 연결(Connection)을 미리 여러 개 생성해 두고, 필요할 때마다 이를 재사용 하는 기술이다.
데이터베이스 연결을 새로 생성하는 것은 시간과 자원을 많이 소모한다.
애플리케이션과 데이터베이스 간의 연결이 네트워크를 통해 이루어지고, 이 과정에서 TCP/IP 핸드셰이크와 같은 여러 단계를 거쳐야한다.
이 과정에서 연결을 맺는 데 상당한 시간이 소모되며 데이터 커넥션 풀을 사용해 미리 생성해 둔 연결을 재사용하면서 연결 생성에 소요되는 시간을 절약하고 애플리케이션의 성능을 향상시킬 수 있다.
데이터베이스 커넥션 풀을 사용하면 데이터베이스 요청이 들어올 때 마다 데이터베이스 연결을 수립하고, 통신한 뒤, 닫는 과정을 거치지 않아도 된다. 데이터베이스 커넥션 풀에는 사전에 데이터베이스와 이미 연결이 수립된 다수의 커넥션들이 존재한다. 커넥션 풀 안의 커넥션들은 데이터베이스 요청이 들어올 때 마다 새롭게 연결을 수립하고 닫는대신 항상 연결을 열린 상태로 유지한다.
WAS(Web Application Server)는 데이터베이스 커넥션이 필요할 때 직접 커넥션을 생성하지 않고, 커넥션 풀 컨테이너로부터 커넥션을 하나 건네받고, 사용을 마치면 반납한다. 이렇게 함으로써 데이터베이스 연결을 열고, 닫는 비용을 절약할 수 있다.
특히 동시에 많은 요청을 처리해야 하는 웹 애플리케이션에서 데이터베이스 성능의 병목 현상을 줄이는 데 큰 도움이 된다.
커넥션 풀의 설정은 애플리케이션의 요구 사항과 데이터베이스 서버의 성능에 따라 달라질 수 있으며, 적절한 모니터링을 통해 지속적으로 조정해야함.
적절한 커넥션 풀 설정은 애플리케이션의 성능과 안정성에 큰 영향을 미친다.
실제 트래픽 패턴을 분석하여 최소 연결 수와 최대 연결 수를 적절히 설정하기.
▶️ 피크 타임에도 충분한 연결을 제공하면서, 비활성 시간에는 자원을 낭비하지 않도록 할 수 있다.
유휴 연결 검사와 연결 유효성 검사를 활성화하여, 항상 유효한 연결만을 유지
▶️ 불필요하게 자원을 소모하는 연결을 정리함으로서 애플리케이션의 안정성을 높이는데 도움이 된다.
애플리케이션의 성능 모니터링 도구를 사용하여 커넥션 풀의 상태를 지속적으로 모니터링하고, 필요에 따라 설정을 조정한다.
▶️ 애플리케이션의 성능을 지속적 관리하고 최적화 할 수 있다.
다양한 커넥션 풀 라이브러리 중에서 애플리케이션의 요구 사항에 가장 적합한 것을 선택.
▶️ ex) HikariCP는 성능과 안정성 면에서 높은 평가를 받는 커넥션 풀 라이브러리 중 하나이다.
이 외 데이터 커넥션 풀 프레임워크로는 대표적으로 Apache Commons DBCP, Tomcat DBCP, HikariCP, Oracle UCP등이 있다.
애플리케이션과 데이터베이스 간의 연결을 효율적으로 관리하여 성능을 향상시킬 수 있다.
데이터베이스에 접근할 때마다 새로운 연결을 생성하고 종료하는 대신, 미리 준비된 연결을 재사용함으로써 성능을 향상시키고 자원 사용을 최적화할 수 있다.
적절한 커넥션 풀 설정과 최적화 전략으르 잘 세운다면 애플리케이션의 성능과 안정성을 크게 향상시킬 수 있다.
DBCP(사이즈를 무식하게 크게 설정하면 DeadLock(교착상태)고 뭐고 문제가 발생하지 않을거 같지만 커넥션도 결국 객체이기 때문에 메모리 공간을 차지한다.
따라서 커넥션 개수와 메모리는 trade-off관계이며 성능 테스트를 통해 최적을 값을 찾아내야한다.
커넥션을 사용하는 주체는 스레드(Thread)이기 때문에 만약 커넥션 풀 사이즈가 스레드 풀 사이즈보다 크면, 스레드 증가로 인해 더 많은 Contect Switching이 발생한다.
Disk 경합 측면에서 성능 한계가 발생하고, 데이터베이스는 하드 디스크 하나 당 하나의 I/O를 처리하므로 블로킹이 발생한다.
▶️ 특정 시점부터는 성능적 증가가 Disk 병목으로 인해 미비해진다.
반대로 커넥션 풀 사이즈가 스레드 풀 사이즈보다 작으면, 스레드가 커넥션이 반환되기를 기다려야 하기 때문에 작업이 지연된다.
커넥션 풀 사이즈와 스레드 풀 사이즈의 균형이 맞더라도 너무 큰 사이즈로 설정하면, 데이터베이스 서버, 애플리케이션 서버의 메모리와 CPU를 과도하게 사용하게 되므로 성능이 저하된다.
따라서 데이터베이스 입자에서 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 요청 수.
사실 저연차에서 애플리케이션을 개발하면서 커넥션 풀까지 고려하기란 쉽지 않다.
아마 알면서도 못하는 경우도 많지만 몰라서 적용하지 못하는 경우가 더 많을 것 같다.
커넥션 풀에 대해 공부했으니 실천할 수 있는 프로젝트를 만난다면 꼭 고려할것이다..!
데이터베이스 커넥션 풀 (Connection Pool)과 HikariCP
A Simple Guide to Connection Pooling in Java
[데이터베이스] Connection Pool이란?
깔끔한 정리 감사해요, 잘 읽었습니다! 🙏🙇🏻♂️