DBCP(Database Connection Pool)

영주·2024년 11월 15일
0

CS

목록 보기
3/3

✅ Spring Boot Application 은 DB 와 연결을 언제 맺을까요?

DB 도 서버와 통신하는 서버라고 이야기했는데요,

  1. 그럼 그 연결은 언제 맺고
  2. 요청은 언제,
  3. 그리고 어떻게 보내게 될까요?

 

🔑 DBCP(Database Connection Pool)

🔑 HikariCP

 

🍪 DB 연결은 언제 맺어지나요?

DB connection : Backend server 와 DB 서버 사이의 연결

  • Application Context 가 초기화될 때 !!
    • Application Context 는 별도의 설정 정보(ex @Configuration 이 적용된 클래스) 를 참고하고 IoC 를 적용하여 빈의 생성, 관계 설정 등의 제어 작업을 총괄합니다.
  • 이때, DataSource 객체를 통해 DBCP(Database Connection Pool)가 생성됩니다.
  • Spring Boot는 기본적으로 HikariCP라는 커넥션 풀 라이브러리를 사용합니다
    • 애플리케이션이 실행될 때, 미리 일정 수의 데이터베이스 커넥션을 생성, 필요에 따라 커넥션을 가져오고 반환하는 방식으로 동작합니다.

 

🍪 API 요청 흐름

백엔드 서버에서 API 요청을 DB 서버로 보내는 과정의 통신은 TCP(연결지향적) 기반으로 동작 합니다.

이 과정에서 connection 을 열고, 닫는 과정에서 꽤 많은 시간이 소요됩니다. ( 3 way, 4 way handshaking)

 

🍪 DBCP 등장 배경

위의 시간적인 비용 때문에 API 응답이 늦어지는 문제점.. 을 해결하기 위해 등장!

 

  1. API 요청을 받게 되면
  2. connection pool 에서 놀고 있는 connection 을 데려와서 이를 바탕으로 쿼리를 보냅니다.
  3. 쿼리 요청, 응답 후 close connection 하게 되면
  4. connection pool 에다가 다시 connection 을 반환합니다.

 

즉, 본격적으로 API 요청을 맺기 전에

요청이 있을 때마다 새로운 커넥션을 생성하는 것이 아니라

백엔드 서버와 DB 서버 간에 DB connection 을 미리 만들어놓고,

재사용함으로써 연결을 open 하고 close 하는 시간을 절약합니다.

 

⇒ 이 Pool 을 DBCP(Database Connection Pool) 라고 부릅니다!

🍑 DB서버 설정 (Mysql 을 가정)

클라이언트는 DB 서버에 요청을 보내는 모든 것들 즉, 여기서는 백엔드 서버가 될 수 있습니다.

중요한 파라미터 2가지를 살펴볼까요?

 

  • max_connections
    • 클라이언트와 DB 서버가 동시에 맺을 수 있는 최대 connection 수
  • wait_timeout
    • 백엔드 서버가 생성한 connection 이 일정 시간 동안 아무 작업도 하지 않을 경우, 자동으로 종료시키기 위해 설정한 시간

 

💡 만약, max_connections 랑 DBCP conection 이 모두 4라면 ?

DB서버 입장에서는, 이미 MAX 만큼 connection 을 맺고 있는 상태가 됩니다.

여기서 만약 백엔드 서버가 바쁘면 connection 들이 바쁘게 사용되는데… 그래서 ‘서버를 한 대 더 도입하자’ 는 의견이 나왔다??! 근데 DB 서버는 이미 connection 을 최대로 맺고 있어서 새로 투입된 백엔드 애플리케이션은 연결을 맺을 수 없습니다!!

→ max_connections 값을 충분히 잘 설정해 주어야 새로운 서버를 투입해도, 에러 없이 정상 작동하게 됩니다.

 

🍑 DBCP 서버 설정 (HikariCP 을 가정)

[공식문서]

https://github.com/brettwooldridge/HikariCP

 

  • minimumIdle : pool 에서 유지하는 최소한의 idle(유휴) connection 수
  • maximumPoolSize : pool이 가질 수 있는 최대 connection 수
    • idle + active 합쳐서 최대 수
  • maxLifeTime : pool에서 각 connection의 최대 수명
  • connectionTimeout : 애플리케이션이 CP로부터 connection 을 얻기 위해 대기할 최대 시간

 

💡 만약, DBCP size 가 4개로 고정이었다 ?

4개에서 3개로 connection 하나가 사라져도 바로 새로 1개를 생성해서 다시 4개로 유지합니다.

connection을 pool 로 반환하지 않으면 사용되고 있는 connection으로 간주되어 maxLifetime 이 동작 하지 않게 됩니다.

connection 이 반환되지 않으면 사용 가능한 connection 이 부족해지고, 추가 요청이 들어오면 connectionTimeout이 발생할 수 있기 때문에, 다 쓴 connection은 pool로 반환을 잘 시켜주는 것이 중요합니다!

image

데이터베이스나 인프라에서 부과하는 connection time limit 보다 몇 초 더 짧아야 합니다. ”

 

⇒ 이런 파라미터들을 적절하게 설정하는 것이 중요 !

 


✅ 그렇다면 디폴트로 맺어지는 연결의 수는 얼마고, 어떤 수가 적정할까요?

🍪 디폴트로 맺어지는 연결의 수는요?

image

별도의 설정을 하지 않으면 HikariCP는 기본적으로 최대 10개의 DB connection 을 관리합니다.

 

HikariCP 에서 권장하기를..

image

  • minimumidle의 기본값은 maximumPoolSize 와 동일한데,
    minimumidle 값을 별도로 설정하지 말고 maximumPoolSize와 동일하게 유지하는 것을 권장합니다.
  • 즉, Connection Pool 의 사이즈가 고정이라는 의미입니다.

 

왜 그렇게 해용?

💡  minimumidle < maximumPoolSize 라고 생각해볼까?

추가 트래픽이 몰릴 때마다 connection 을 만들어주어야 하는데, 아까 살펴보았던 것처럼 connection 을 만드는 과정은 시간이 많이 듭니다. connection 을 만들어 주는 속도보다, 더 빠른 속도로 트래픽이 몰려오게 되면 백엔드 서버의 응답이 느려질 수 있습니다.

⇒ 애초에 처음부터 적절한 개수로 Connection Pool size를 고정해서 사용하라! 는 말

⇒ 왜냐? 트래픽이 급증해도 새로운 connection 생성하느라 시간낭비 안하고 즉각 대응이 가능하니까!

 

🍪 그렇다면 적정한 connection 수는요?

딱 정해져 있는 정답은 없다 !!!
: 모니터링 & 부하 테스트 를 통해…..

1️⃣ 모니터링 환경을 구축

CPU, 메모리, 서버 스레드 수, DBCP 상태 등을 파악한다.

 
2️⃣ 부하 테스트 진행

request per second(백엔드 시스템의 전체적인 처리량) & avg response time(API 성능확인)을 확인

  • request per second : 트래픽 늘어나다가 어느 순간에는.. RPS가 일정하게 유지, avg response time또한 일정하게 유지되다가 계속 증가. → 이 유지, 증가 되는 병목 포인트들에서 지표들이 어떻게 되는지 모니터링 해야겠다!

 
3️⃣ 백엔드 서버 & DB 서버의 등의 리소스(CPU, MEM) 사용률 확인

  • 백엔드 서버의 리소스 사용률 많으면 많으면 백엔드 서버 추가!
  • DB서버의 리소스 사용률 많으면.. 부하 낮추는 방법 여러가지 존재함 (생략) → But, 둘 다 괜찮은데 병목 포인트가 생기면??

 
4️⃣ 추가적인 지표 확인 1

  1. thread per request(요청당 하나의 스레드를 사용) 모델이라면 → active thread 수 확인 → 괜찮은데?
  2. 그럼 DBCP의 active connection 수 확인 → 헉 이게 문제였군.
  3. maximumPoolSize 를 올려가면서 다시 부하 테스트

⇒ 근데, connection pool 사이즈를 늘려도 어느 순간부터 성능이 개선이 안된다면??

 
5️⃣ 추가적인 지표 확인 2

  • DB 서버의 max_connections 의 수 확인해서 필요하면 늘린다!

⇒ 사용할 백엔드 서버 수(CPU등등)를 전체적으로 고려하여 DBCP의 max pool size 결정

⇒ 종합적으로 고려하면서 적절한 DB의 connection 수 설정

 
요약

  1. DB의 max_connections 수 확인 → 필요 시 조정
  2. 그를 기준으로 백엔드 서버 수를 고려해서
  3. max_connections 초과하지 않도록 각 서버의 DBCP 별로 max pool size를 어떻게 가질건지 설정

 
여러 종류의 DBCP가 존재함! HikariCP, Apache Commons DBCP..

자기가 쓰는 DBCP 를 잘 숙지하는 것이 중요함~

 
(+) 네이버에서 쓴 Commons DBCP

https://d2.naver.com/helloworld/5102792

profile
BE Developer

0개의 댓글