Blog

DB 커넥션 풀: 연결을 빌리고 돌려주는 흐름

Spring Boot에서 DB에 접근할 때 사용하는 커넥션 풀을 공부했습니다.

요청마다 새로 연결하면 드는 비용

서비스가 요청을 처리하려면 DB에 접근해야 할 때가 있습니다. TCP/IP로 DB에 새로 연결하는 경우에는 TCP 연결과 인증 등 준비 작업이 필요합니다. SQL을 실행하는 시간에 연결을 만드는 시간까지 더해지는 셈입니다.

데이터베이스 커넥션 풀은 여러 커넥션을 관리해 두었다가 재사용하는 방식입니다. 매번 연결을 새로 만들지 않아도 됩니다.

빌리고, 사용하고, 반납합니다

당시에는 서버가 시작하면서 설정된 커넥션을 확보해 보관한다고 이해했습니다. 요청이 들어오면 풀에서 커넥션을 하나 빌려 DB 작업을 합니다. 작업을 끝내면 풀에 돌려줍니다. 반납된 커넥션은 다음 요청이 다시 사용할 수 있습니다.

시작 시 확보하는 수와 방식은 구현과 설정에 따라 달라집니다. 그래서 시작과 동시에 10개를 준비하지 않는 풀도 있습니다.

Spring Boot에서 사용하는 풀 구현으로 HikariCP를 공부했습니다. 당시 기본값을 10개라고 적었는데 여기서 10개는 풀이 10개라는 뜻이 아니라 한 풀이 관리하는 커넥션 수에 관한 설정입니다.

HikariCP 설정 문서에 따르면 maximumPoolSize의 기본값은 10입니다. 사용 중인 커넥션과 유휴 커넥션을 합친 최대 개수입니다. 커넥션을 확보하지 못하면 connectionTimeout까지 기다립니다.

커넥션을 모두 쓰고 있으면 어떻게 될까요?

풀의 최대 커넥션 수가 10개이고 동시 사용자가 100명이라고 가정했습니다. 사용자 100명이 동시에 DB 커넥션 100개를 필요로 하는지는 상황마다 다릅니다. 하지만 이미 10개가 모두 사용 중인데 추가로 DB 작업이 들어오면 커넥션을 바로 빌릴 수 없습니다.

당시에는 이를 “큐에 요청을 넣고 순차적으로 처리한다”고 이해했습니다. 하지만 이미 빌린 여러 커넥션에서는 작업이 동시에 진행될 수 있습니다. 모든 DB 작업을 하나씩 직렬 처리하는 구조와는 다릅니다.

기다리는 동안 다른 작업이 커넥션을 반납하면 사용할 수 있습니다. 정해진 대기 시간을 넘기면 타임아웃이 발생합니다. 풀 크기를 정할 때는 사용자 수만 보지 말고 서비스가 커넥션을 얼마나 오래 사용하는지도 함께 고려해야 합니다.