DB 도 서버와 통신하는 서버라고 이야기했는데요,
🔑 DBCP(Database Connection Pool)
🔑 HikariCP
DB connection : Backend server 와 DB 서버 사이의 연결
- Application Context 가 초기화될 때 !!
- Application Context 는 별도의 설정 정보(ex @Configuration 이 적용된 클래스) 를 참고하고 IoC 를 적용하여 빈의 생성, 관계 설정 등의 제어 작업을 총괄합니다.
- 이때, DataSource 객체를 통해 DBCP(Database Connection Pool)가 생성됩니다.
- Spring Boot는 기본적으로 HikariCP라는 커넥션 풀 라이브러리를 사용합니다
- 애플리케이션이 실행될 때, 미리 일정 수의 데이터베이스 커넥션을 생성, 필요에 따라 커넥션을 가져오고 반환하는 방식으로 동작합니다.
백엔드 서버에서 API 요청을 DB 서버로 보내는 과정의 통신은 TCP(연결지향적) 기반으로 동작 합니다.
이 과정에서 connection 을 열고, 닫는 과정에서 꽤 많은 시간이 소요됩니다. ( 3 way, 4 way handshaking)
위의 시간적인 비용 때문에 API 응답이 늦어지는 문제점.. 을 해결하기 위해 등장!
즉, 본격적으로 API 요청을 맺기 전에
요청이 있을 때마다 새로운 커넥션을 생성하는 것이 아니라
백엔드 서버와 DB 서버 간에 DB connection 을 미리 만들어놓고,
재사용함으로써 연결을 open 하고 close 하는 시간을 절약합니다.
⇒ 이 Pool 을 DBCP(Database Connection Pool)
라고 부릅니다!
클라이언트는 DB 서버에 요청을 보내는 모든 것들 즉, 여기서는 백엔드 서버가 될 수 있습니다.
중요한 파라미터 2가지를 살펴볼까요?
max_connections
wait_timeout
💡 만약, max_connections 랑 DBCP conection 이 모두 4라면 ?
DB서버 입장에서는, 이미 MAX 만큼 connection 을 맺고 있는 상태가 됩니다.
여기서 만약 백엔드 서버가 바쁘면 connection 들이 바쁘게 사용되는데… 그래서 ‘서버를 한 대 더 도입하자’ 는 의견이 나왔다??! 근데 DB 서버는 이미 connection 을 최대로 맺고 있어서 새로 투입된 백엔드 애플리케이션은 연결을 맺을 수 없습니다!!
→ max_connections 값을 충분히 잘 설정해 주어야 새로운 서버를 투입해도, 에러 없이 정상 작동하게 됩니다.
[공식문서]
https://github.com/brettwooldridge/HikariCP
minimumIdle
: pool 에서 유지하는 최소한의 idle(유휴) connection 수maximumPoolSize
: pool이 가질 수 있는 최대 connection 수maxLifeTime
: pool에서 각 connection의 최대 수명connectionTimeout
: 애플리케이션이 CP로부터 connection 을 얻기 위해 대기할 최대 시간
💡 만약, DBCP size 가 4개로 고정이었다 ?
4개에서 3개로 connection 하나가 사라져도 바로 새로 1개를 생성해서 다시 4개로 유지합니다.
connection을 pool 로 반환하지 않으면 사용되고 있는 connection으로 간주되어 maxLifetime
이 동작 하지 않게 됩니다.
connection 이 반환되지 않으면 사용 가능한 connection 이 부족해지고, 추가 요청이 들어오면 connectionTimeout이 발생할 수 있기 때문에, 다 쓴 connection은 pool로 반환을 잘 시켜주는 것이 중요합니다!
“데이터베이스나 인프라에서 부과하는 connection time limit 보다 몇 초 더 짧아야 합니다. ”
별도의 설정을 하지 않으면 HikariCP는 기본적으로 최대 10개의 DB connection 을 관리합니다.
HikariCP 에서 권장하기를..
minimumidle
의 기본값은 maximumPoolSize
와 동일한데,
왜 그렇게 해용?
💡 minimumidle < maximumPoolSize
라고 생각해볼까?
추가 트래픽이 몰릴 때마다 connection 을 만들어주어야 하는데, 아까 살펴보았던 것처럼 connection 을 만드는 과정은 시간이 많이 듭니다. connection 을 만들어 주는 속도보다, 더 빠른 속도로 트래픽이 몰려오게 되면 백엔드 서버의 응답이 느려질 수 있습니다.
⇒ 애초에 처음부터 적절한 개수로 Connection Pool size를 고정해서 사용하라! 는 말
⇒ 왜냐? 트래픽이 급증해도 새로운 connection 생성하느라 시간낭비 안하고 즉각 대응이 가능하니까!
딱 정해져 있는 정답은 없다 !!!
: 모니터링 & 부하 테스트 를 통해…..
1️⃣ 모니터링 환경을 구축
CPU, 메모리, 서버 스레드 수, DBCP 상태 등을 파악한다.
2️⃣ 부하 테스트 진행
request per second(백엔드 시스템의 전체적인 처리량) & avg response time(API 성능확인)을 확인
3️⃣ 백엔드 서버 & DB 서버의 등의 리소스(CPU, MEM) 사용률 확인
4️⃣ 추가적인 지표 확인 1
⇒ 근데, connection pool 사이즈를 늘려도 어느 순간부터 성능이 개선이 안된다면??
5️⃣ 추가적인 지표 확인 2
⇒ 사용할 백엔드 서버 수(CPU등등)를 전체적으로 고려하여 DBCP의 max pool size 결정
⇒ 종합적으로 고려하면서 적절한 DB의 connection 수 설정
요약
여러 종류의 DBCP가 존재함! HikariCP, Apache Commons DBCP..
자기가 쓰는 DBCP 를 잘 숙지하는 것이 중요함~
(+) 네이버에서 쓴 Commons DBCP