본문 바로가기
DataBase/MySQL

[MySQL] DBCP 개념, 설정

by 제우제우 2024. 11. 16.

참고 자료 

유투브 쉬운코드 DBCP

DPCP(DB connection pool)사용 X 문제점 

해당 그림은 백엔드 서버와 DB 서버의 통신 과정이다. 

백엔드 서버와 DB 서버는 네트워크를 통해서 통신하는데 이때 TCP 기반으로 동작한다. 

TCP는 연결지향적 통신 프로토콜인데 높은 송수신 신뢰성이 특징이다.

 

쿼리를 요청하기 전에 open connection 쿼리 응답을 받고 close connection 과정이 있는데

open/close connection 과정이 간단하지 않다. 

 

open connection (3-way Handshake)

TCP 연결을 설정할 때 거치는 과정이다.

 

SYN(Synchronize)

클라이언트(백엔드 서버)가 서버(DB 서버)와 연결을 시작하려면, 먼저 DB 서버로 SYN 패킷을 보낸다. 

이 패킷은 연결을 시작하려는 요청을 의미한다. 

 

SYN-ACK(연결 수락 및 준비)

DB 서버는 SYN 패킷을 받고, 이에 대한 응답으로 SYN-ACK 패킷을 보낸다. 

이 패킷은 연결을 수락했으며, 클라이언트(백엔드 서버)의 요청을 받았다는 의미이다.

 

ACK(Acknowledgement)

백엔드 서버는 DB 서버로부터 SYN-ACK 패킷을 받고, 이를 확인하는 ACK를 보낸다.

이로써 클라이언트는 서버 간의 연결이 설정된다. 

 

close connection (4-way Handshake)

연결을 종료할 때는 4-way handshake 과정을 거친다.

 

FIN(FINISH)

연결을 종료하려는 쪽(클라이언트/백엔드 서버)이 FIN 패킷을 DB 서버로 보낸다. 

이는 더이상 데이터를 보내지 않겠다를 의미한다. 

 

ACK(Acknowledgement)

DB 서버는 백엔드 서버로부터 FIN 패킷을 받고, 이에 대한 응답으로 ACK 패킷을 보낸다.

이는 FIN을 받았고, 종료 준비를 하고 있다는 응답이다. 

 

FIN

DB 서버는 연결 종료 준비가 되었음을 나타내기 위해 자신의 FIN 패킷을 보낸다. 

 

ACK - 연결 종료 완료 

마지막으로 백엔드 서버는 DB 서버로부터 받은 FIN에 대해 ACK 패킷을 보낸다.

이 ACK 패킷은 DB 서버의 요청 종료를 받아들였고, 연결을 종료했다는 최종 확인 응답이다. 

이로써 TCP 연결이 완전히 종료된다. 

 

DBCP 사용 X 문제점 

매번 connection을 열고 닫는 시간적인 비용이 발생한다. 

서비스의 성능에 좋지 않다.

DPCP 개념과 원리 

 

DBCP 동작 원리

애플리케이션 서버(백엔드 서버)가 시작되면 미리 커넥션 풀에 DB 서버와의 커넥션을 미리 생성한다. (커넥션 개수는 설정에 따라 다르다)

클라이언트 API 요청이 오고 DB 커넥션이 필요하면 커넥션 풀에서 커넥션을 받아온다.

커넥션을 통해 (쿼리 요청, 쿼리 응답) 

클라이언트 API 요청에서 더 이상 커넥션이 필요하지 않으면 커넥션 풀에 반환한다.

이때 중요한 점은 커넥션 자체를 물리적으로 끊는 게 아니라 반환한다는 게 포인트이다. 

 

이렇게 커넥션을 반환하고 재사용함으로써 열고 닫는 시간(3-way-handshake, 4-way-handshake)과정이 없으니까 

클라이언트에게 응답 반환도 빠르게 가능하고 백엔드 서버의 전체적인 성능 또한 향상된다.

이런 커넥션 풀을 DataBase Connection Pool 즉 DBCP 라고 부른다. 

DPCP 설정 

백엔드 서버: spring boot 2.0

DB 서버: MySQL

 

DB connection은 backend server와 DB server 사이의 연결을 의미하기 때문에

backend server와 DB server 각각에서의 설정 방법을 잘 알고 있어야 한다 

MySQL 설정 

MySQL max_connections 

max_connections: client와 맺을 수 있는 최대 connnection 수

ex)

MySQL max_connections 4로 지정 

백엔드 서버 DBCP에 생성 가능한 최대 커넥션은 4개가 된다. 

백엔드 서버에  DB 커넥션 관련 부하가 생겨서 똑같은 코드를 가지는 백엔드 서버를 추가 투입(스케일 아웃)해도 

max_connections가 4이기 때문에 의미가 없다.

설정을 주의해서 하자

 

MySQL wait_timeout

wait_timeout: connection이 inactive할 때 다시 요청이 오기까지 얼마의 시간을 기다린 뒤에 close할 것인지를 결정 

ex)

비정상적인 connection 종료 

connection 다 쓰고 반환이 안된 경우 

네트워크가 단절된 경우 

 

이런 경우에도 MySQL 서버에서는 4-way-handshake가 일어나지 않았기 때문에 connection을 계속 유지한다

이런 비정상적인 connection은 사용되지 않으니까 close 해야 한다. 

즉, 해당 설정은 connection을 언제 비정상적인 커넥션으로 인지할지에 대한 시간이다. 

DBCP 설정 (HikariCP)

HikariCP는 스프링 부트 2.0부터 default로 사용하는 DBCP

 

idle & active connection 개념 

idle 커넥션: 클라이언트 요청에 의해 사용되지 않고 대기 상태로 남아 있는 커넥션

active 커넥션: 현재 클라이언트 요청을 처리 중인 커넥션(사용 중)

 

maximumPoolSize

pool이 가질 수 있는 최대 connection 수 

idle과 active(in-use) connection 합쳐서 최대 수

 

minimumIdle

pool에서 유지하는 최소한의 idle connection 수 

idle connection 수가 minimumIdle 보다 작고, 전체 connection 수도 maximumPoolSize 보다 작다면

신속하게 추가로 connection을 만든다. 

 즉, maximumPoolSize 파라미터의 우선순위가 더 높다. 

 

hicariCP 메뉴얼 권장사항 

기본값: maximumPoolSize = minimumIdle 

즉, pool size 고정해라 

 

해당 메뉴얼의 의미 

트래픽이 몰려올 때 커넥션을 생성하면 생성 비용(handshake) 때문에 응답이 느려질 수 있다. 

그러니 애초에 처음부터 최대 사이즈로 유지하고 close 하지 말자 

 

maxLifetime

pool에서 connection의 최대 수명 

maxLifetime을 넘기면 idle일 경우 pool에서 바로 제거

active인 경우 pool로 반환된 후 제거 

 

주의점1 

만약 코드상의 버그로 커넥션이 pool로 반환이 안되면 maxLifeTime 동작을 안한다. 

이때 커넥션의 LifeTime이 MySQL 서버의 wait_timeout을 넘기면 connection이 끊긴다. 

만약 이때 해당 커넥션을 사용하면 이미 connection이 끊겼기 때문에 exception이 발생한다.

그러니까 pool로 반환을 꼭 하자

 

주의점2

DB의 connection time limit(MySQL wait_timeout)보다 몇 초 짧게 설정하자 

 

connectionTimeout

pool에서 connection을 받기 위한 대기 시간