[DataBase] DBCP(DataBase Connection Pool)
DBCP
DBCP는 DataBase Connection Pool. 즉, DB와 연결을 맺어놓은 것들이 쌓여있는 곳이라고 할 수 있다. 보통 Application과 DB는 TCP 통신을 이용하여 연결을 하게 되는데 TCP 연결은 3-way hand shaking이 필요하기 때문에 시간과 자원이 많이 소모된다. Application으로 client 요청이 하나가 오더라도 DB로의 접근은 여러 번이 될 수 있기 때문에 매번 요청이 올 때마다 DB connection을 맺는 것은 좋은 방법이 아니다. 그래서 application이 실행될 때 DB와 미리 여러 개의 connection을 맺어두고 DB에 접근할 일이 생기면 pool에서 connection을 가져와서 사용하고 다시 connection을 반납하는 구조를 만들어 DB를 좀 더 효율적으로 사용하게 만들어 주는 기술이 DBCP이다.
스프링 부트는 2.0 버전 이전에는 Tomcat JDBC Connection Pool을 기본으로 사용하고 있었으나 2.0 버전부터는 HikariCP의 효율성을 더 높게 보고 기본 DBCP로 HikariCP를 사용하고 있다. 많이 사용되고 있는 Spring과 MySQL 조합에서의 connection과 관련된 파라미터들을 살펴보자.
MySQL
max_connections
DB가 client와 맺을 수 있는 최대 연결 수. Application에서 더 많은 연결을 요청해도 이 값 이상의 connection은 맺어지지 않는다. MySQL 8.0버전 기준으로 default 값은 151이다.
wait_timeout
DB와 client가 연결 후 쿼리가 올 때까지 기다리는 시간이다. 연결을 맺은 후 어떠한 이유로 인해 application에서 연결이 반납이 되지 않고 connection만 연결되어 있는 상황이 생길 수 있다. 이때, 이러한 비정상적인 연결이 많아지면 실제 요청을 처리할 수 있는 연결이 줄어들기 때문에 특정 시간 동안 요청이 오지 않는 경우 연결을 끊게 된다. MySQL 8.0 버전 기준으로 default 값은 28800초 약 8시간이다
Spring
maximum-pool-size(default : 10)
Connection pool이 가질 수 있는 최대 connection 수이고, default 값은 10이다. maximum-pool-size를 설정할 때, 만약 여러개의 application에서 DB에 요청할 경우 고려해야될 상황이 있다. 바로 DB의 max_connections인데 DB의 max_connections 값은 여러 개의 application과 connection 개수를 고려하기 때문에 application이 늘어날 경우 maximum-pool-size를 아무리 늘려도 DB의 max_connections 개수 이상의 연결이 맺어질 수 없기 때문이다.
minumum-idle(default: same as maximum-pool-size)
Connection pool에서 유지하는 최소한의 idle connection 수. default 값은 maximum-pool-size와 같다. maximum-pool-size 보다 큰 경우 maximum-pool-size보다 큰 값을 가질 수 없기 때문에 의미가 없는 값이 되어버리고, maximum-pool-size 보다 작은 경우에는 connection을 적게 유지하다가 늘어나는 경우 connection을 추가로 맺어야되기 때문에 maximum-pool-size와 같은 값을 설정하는 것이 성능상 좋다.
max-lifetime(default: 1800000ms)
Connection pool에서 최대로 유지할 수 있는 connection 별 수명. default 값은 1800000 ms로 30분이다. Connection이 사용 중이라면 반환된 후 제거된다. max-lifetime은 앞서 살펴본 DB의 wait_timeout보다 짧게 설정되어야 한다. wait_timeout이 더 짧은 경우에는 application에서 connection을 이용해 DB에 접근하려고 할 때 DB에서 이미 wait_timeout이 지나 connection을 끊어버렸을 수도 있다. 결국 connection을 관리하는 주체가 누구인지에 대한 것인데 connection을 먼저 맺는 것도, 요청을 보내는 것도 connection pool에서 시작되니 connection pool이 모르는 채로 DB에서 먼저 연결을 끊는 경우를 방지하는 것으로 생각이 된다.
idle-timeout(default: 600000 ms)
Connection pool에서 idle 상태로 있는 connection이 해제되는 시간이다. default 값은 600000 ms 10분이다.
이 설정은 maximum-pool-size와 minimum-idle이 같은 경우에는 쓰이지 않는다. maximum-pool-size와 minumum-idle이 같은 경우는 connection이 하나도 사용되지 않더라도 idle connection의 개수가 항상 최대만큼 유지되기 때문에 해제될 connection이 없기 때문이다. 또한 idle-timeout이 max-lifetime보다 큰 경우도 idle-timeout으로 connection이 해제되기 전에 max-lifetime이 먼저 동작해서 connection이 해제되기 때문에 이 경우에도 동작하지 않는다.