1. DBCP?
데이터베이스 연결(Connection)을 효율적으로 관리하기 위해 사용되는 기술.
데이터베이스 연결을 매번 생성하고 종료하는 작업은 비용이 많이 든다!
그래서 미리 일정 수의 연결을 생성해두고 필요할 때 재사용하도록 도와주는 것이 DBCP
2. 필요한 이유
데이터베이스 커넥션을 획득할 때는 다음과 같은 복잡한 과정을 거친다.
1. 애플리케이션 로직은 DB 드라이버를 통해 커넥션을 조회한다.
2. DB 드라이버는 DB와 TCP/IP 커넥션을 연결한다. 물론 이 과정에서 3 way handshake 같은 TCP/IP
연결을 위한 네트워크 동작이 발생한다.
3. DB 드라이버는 TCP/IP 커넥션이 연결되면 ID, PW와 기타 부가정보를 DB에 전달한다.
4. DB는 ID, PW를 통해 내부 인증을 완료하고, 내부에 DB 세션을 생성한다.
5. DB는 커넥션 생성이 완료되었다는 응답을 보낸다.
6. DB 드라이버는 커넥션 객체를 생성해서 클라이언트에 반환한다.
이게 너무 복잡하고 시간도 많이 소요되니까 커넥션 풀을 사용하는 것!
장점
비용절감
커넥션을 매번 열고 닫는 것은 시간과 자원을 많이 소모한다.
커넥션 풀을 사용하면 커넥션을 재사용해 성능을 높일 수 있다.
성능향상
DB 커넥션 생성/종료 과정을 줄여 응답속도가 빨라짐.
트래픽이 급증해도 커넥션 풀로 안정적인 서비스 제공 가능.
안정성
커넥션을 일정 수만 유지해 DB 과부하 방지함
유휴 커넥션은 자동으로 정리하거나 갱신함
DBCP 동작 원리
1. 애플리케이션 시작 시 미리 커넥션 풀을 생성
2. 요청 발생 시 커넥션 풀에서 사용 가능한 커넥션을 할당
3. 작업 완료 후 커넥션을 닫지 않고 반환
4. 커넥션 풀이 부족하면 새 커넥션 생성 또는 대기
5. 일정 시간이 지난 유휴 커넥션은 자동으로 제거
추천되는 것
HikariCP
경량화와 고성능 커넥션 풀
빠른 응답 속도와 효율적인 자원관리를 해줌
Spring boot 기본으로 채택됨!
DBCP 주요 설정 항목
1. 기본 커넥션 설정
setJdbcUrl(String url) | DB 연결을 위한 JDBC URL 설정 | "jdbc:mysql://localhost:3306/mydb" |
setUsername(String username) | DB 연결을 위한 사용자 이름 설정 | "root" |
setPassword(String password) | DB 연결을 위한 비밀번호 설정 | "password" |
setDriverClassName(String className) | JDBC 드라이버 클래스 설정 | "com.mysql.cj.jdbc.Driver" |
2. 커넥션 풀 크기 설정
setMaximumPoolSize(int maxPoolSize) | 최대 커넥션 수 설정 | 10 | 20 |
setMinimumIdle(int minIdle) | 최소 유휴 커넥션 수 설정 | 동일 | 5 |
setIdleTimeout(long milliseconds) | 유휴 커넥션 유지 시간(ms) | 600,000 | 300,000 |
setMaxLifetime(long milliseconds) | 커넥션 최대 생존 시간 설정(ms) | 1,800,000 | 1,800,000 |
setConnectionTimeout(long milliseconds) | 커넥션 요청 대기 시간 설정(ms) | 30,000 | 10,000 |
3. 커넥션 테스트 및 검증
setConnectionTestQuery(String sql) | 커넥션 유효성 검사용 쿼리 설정 | "SELECT 1" |
setValidationTimeout(long milliseconds) | 커넥션 유효성 검사 타임아웃(ms) 설정 | 5,000 |
setInitializationFailTimeout(long milliseconds) | 풀 초기화 실패 시 대기 시간(ms) | 1,000 |
4. 성능 최적화 관련 설정
setAutoCommit(boolean autoCommit) | 커넥션 Auto Commit 설정 | true |
setReadOnly(boolean readOnly) | 커넥션 읽기 전용 설정 | false |
setIsolateInternalQueries(boolean flag) | 내부 쿼리를 트랜잭션에서 분리할지 여부 | false |
setLeakDetectionThreshold(long milliseconds) | 커넥션 누수 감지 시간 설정(ms) | 0 (비활성화) |
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
public class HikariCPExample {
private static HikariDataSource dataSource;
static {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("root");
config.setPassword("password");
config.setDriverClassName("com.mysql.cj.jdbc.Driver");
// 커넥션 풀 설정
config.setMaximumPoolSize(20); // 최대 커넥션 수
config.setMinimumIdle(5); // 최소 유휴 커넥션
config.setConnectionTimeout(10000); // 커넥션 요청 대기 시간 (10초)
config.setIdleTimeout(300000); // 유휴 커넥션 유지 시간 (5분)
config.setMaxLifetime(1800000); // 커넥션 최대 수명 (30분)
// 유효성 검사 쿼리
config.setConnectionTestQuery("SELECT 1");
// 누수 감지 (5초 이상 반환 안 되면 경고)
config.setLeakDetectionThreshold(5000);
// 커넥션 풀 이름
config.setPoolName("MyHikariCP");
// 데이터 소스 초기화
dataSource = new HikariDataSource(config);
}
public static Connection getConnection() throws Exception {
return dataSource.getConnection();
}
public static void close() {
if (dataSource != null) {
dataSource.close();
}
}
}
'DB' 카테고리의 다른 글
[DB] Replication으로 데이터베이스 동기화 (DRS) (0) | 2024.12.03 |
---|---|
[SQL] SQL QUERY 기본 문법 (1) | 2024.11.29 |
[DB] SQL (2) | 2024.11.27 |
[DB] 데이터베이스(DB)란?? (0) | 2024.11.27 |
[DB] 가상환경에서 DB 초기설정 (0) | 2024.11.27 |