2025. 2. 27. 11:59ㆍCS/DB
스프링부트 애플리케이션 성능을 최적화하기 위한 방법 중 DB Connection Pool을 늘리는 방법이 있다.
이번 글은 DB Connection Pool이 무엇인지 알아보고자 한다.
DB Connection Pool이란 애플리케이션과 DB서버가 통신할 수 있도록 하는 기능이다.
아래 코드는 Java의 DB Connection을 JDBC를 이용해 구현한 예이다.
public Connection getConnection() {
try {
return DriverManager.getConnection("jdbc:mysql://" + SERVER + "/" + DATABASE + OPTION, USERNAME, PASSWORD);
} catch (final SQLException e) {
System.err.println("DB 연결 오류:" + e.getMessage());
e.printStackTrace();
return null;
}
}
연결에 성공하면 Connection 객체가 반환된다.
Connection 객체가 반환되는 과정
- DB 드라이버 로드 : 우선 사용하려는 DB에 해당하는 JDBC드라이버를 로드해야한다.
- DB 연결 정보 설정 : 연결하려는 DB의 URL, 사용자 이름, 비밀번호 등의 연결정보를 설정한다.
- Connection 객체 생성 : DriverManager클래스를 사용하여 DB와 연결하고 이 연결을 나타내는 Connection객체를 얻는다.
Connection 이후
- Connection 객체 사용 : 반환된 Connection 객체를 사용하여 DB관련 작업을 수행한다.
- 연결 종료 : DB작업을 마치면, Connection 객체를 명시적으로 닫아야한다. 리소스 누수를 방지하고 DB연결을 제대로 해제하기 위함이다. connection.close();
DB를 연결할때마다 Connection 객체를 새로 만드는 것이 좋지 않은 이유
- 네트워크 비용
- DB연결을 설정하는 과정은 네트워크 통신을 동반한다.
- 새로운 Connection객체를 생성할때마다 DB서버와 네트워크 연결을 해야하며, 이 과정은 일정 시간이 소요된다.
- 따라서, 빈번한 Connection생성은 불필요한 네트워크 비용을 발생시킨다.
- 리소스 사용
- 각 Connection 객체는 DB서버의 연결세션을 나타낸다.
- DB서버는 동시에 처리할 수 있는 연결 세션 수에 제한이 있으며, 무분별한 Connection생성은 서버 리소스를 소모할 수 있다.
- 비용적 측면
- Connection객체 생성은 시간과 메모리를 소모한다.
- 특히 DB연결 설정 및 인증과정은 비용이 큰 작업이다.
DB Connection Pool
위에서 살펴본 Connection 객체의 반복적인 생성과 해제를 피하고 효율적으로 DB연결을 관리하기 위해 Connection Pool이 사용된다.
DB Connection Pool이란, DB의 추가 요청이 필요할 때, 연결을 재사용할 수 있도록 관리되는 DB연결의 캐시이다.
간단하게 말하자면, 애플리케이션 시작 시, 미리 일정 수의 Connection객체를 생성하여 Pool에 보관한다.
이후에 DB작업이 필요할때마다 Pool에서 Connection객체를 가져다 사용하고 작업이 끝나면 Pool에 반환한다.
Connection Pool 장점
- 성능 향상
- 미리 연결된 DB연결을 Pool에 유지하고 요청이 들어올때마다 해당 연결을 재사용함으로써 응답시간을 단축하고 애플리케이션의 성능을 향상시킨다.
- 자원 관리
- 연결을 생성하고 유지하는데 필요한 자원을 최적화한다. 불필요한 연결을 만들지 않고 연결을 재사용함으로써 메모리와 CPU등의 자원을 효율적으로 관리할 수 있다.
- 동시성 관리
- 동시에 여러 요청을 처리할 수 있는 연결을 제공하므로, 다수의 사용자가 동시에 애플리케이션에 접속해도 안정적으로 처리할 수 있다.
- 연결 풀링
- 연결의 개수를 제한하고, 초과하는 요청이 들어올 경우 대기하도록 처리함으로써, DB서버의 부하를 관리하고 과부하를 방지한다.
- Connection 오버헤드 감소
- 반복적인 DB연결/해제 작업에 따른 오버헤드를 감소시킨다.
Connection Pool 단점
- 리소스 사용
- 일정 수의 연결을 미리 생성 및 유지해야하므로, 메모리 등의 리소스를 일정 부분 소비한다.
- 설정 및 관리의 복잡성
- 다양한 환경에서 최적의 성능을 발휘하기 위해서는 일정한 관리와 모니터링이 필요하다.
- 설정 파라미터의 조절이 필요한 경우에는 초기 설정 및 튜닝에 시간이 소요될 수 있다.
- 커넥션 누수
- 애플리케이션에서 연결을 올바르게 반환하지 않거나 예외가 발생하는 경우, 커넥션 풀에서 연결이 제대로 반환되지 않을 수 있다. 이 경우, 커넥션 누수가 발생할 수 있다.
Connection Pool 사용 예시
Connection Pool의 종류 중 하나인 HikariCP를 사용한 예시코드이다.
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ConnectionPoolExample {
public static void main(String[] args) {
// HikariCP 설정
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");
config.setUsername("username");
config.setPassword("password");
// HikariCP 데이터소스 생성
HikariDataSource dataSource = new HikariDataSource(config);
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
// 커넥션 풀에서 커넥션 획득
connection = dataSource.getConnection();
// SQL 쿼리 실행
String sql = "SELECT * FROM users WHERE id = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 1); // 예시로 사용자 ID가 1인 사용자 조회
resultSet = preparedStatement.executeQuery();
// 결과 처리
if (resultSet.next()) {
String username = resultSet.getString("username");
System.out.println("Username: " + username);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 리소스 해제 (역순으로 해제)
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close(); // 커넥션을 풀에 반환
} catch (SQLException e) {
e.printStackTrace();
}
}
// HikariCP 데이터소스 종료
if (dataSource != null) {
dataSource.close();
}
}
}
}
Connection Poo이 커지면 성능이 무조건 좋아질까?
Connection Pool을 크게 설정하면
- 많은 메모리를 사용하지만, 동시에 많은 사용자가 대기 시간이 줄어들어 성능이 향상될 수 있다.
Connection Pool을 작게 설정하면
- 메모리 소모는 줄어들지만, 동시 접속자가 많아지면 대기시간이 길어질 수 있다.
Hikari CP는 적절한 Connection Pool의 크기를 1 connections = ((core_count) * 2) + effective_spindle_count) 로 정의하고 있다.
'CS > DB' 카테고리의 다른 글
키(Key) (슈퍼키, 후보키, 기본키, 대체키, 외래키) / 무결성 제약조건 (도메인 무결성, 개체무결성, 참조무결성) (1) | 2024.03.04 |
---|---|
릴레이션 스키마와 릴레이션 인스턴스 개념 (0) | 2024.03.04 |
데이터 독립성과 RDBMS (0) | 2024.03.04 |
DBMS, 스키마, 3단계 데이터베이스 구조 (0) | 2024.03.04 |
파일시스템과 데이터베이스의 차이점 (0) | 2024.03.04 |