* 개요
DataSource를 여러개 만드는 과정에서, connection Pool로 Hikari를 이용하는 예제를 보았습니다. Hikari는 성능이 좋아서 쓴다고 생각은 했지만, 어느정도 성능이 좋고 어떤 개념을 가지고 있는지 확인하려고 합니다.
* Hikari란?
Hikari는 connection pooling을 제공하는 JDBC DataSource의 구현체입니다.
이 프레임워크가 다른 connection pooling 보다 가장 빠른 이유는 몇몇 바이드코드 레벨의 구현이 있으며, 마이크로 최적화, ArrayList<Staement> 사용 대신 FastList 직접 구현으로 처음부터 끝까지 모든 것을 스캔하는 과정 생략 등이 있습니다.
실제 성능의 테스트 결과를 보고 싶다면 다음 벤치마크를 확인해주세요.
Hikari 설정에 앞서서, Hikari가 관리하는 Connecton Pool이 무엇인지, Hikari를 구현하고자 하는 Datasource가 무엇인지 알아보겠습니다.
* DataSource
데이터소스(DataSource)는 물리적인 데이터베이스에 연결하기 위한 팩토리입니다. 데이터소스는 데이터베이스에 연결하기 위해 이름/비밀번호, URL을 사용합니다. 보통 데이터소스는 커넥션을 얻기 위해 사용됩니다. JDBC API가 제공하는 데이터소스 객체를 사용하면, DriverManager를 사용하지 않고 DB연결을 할 수 있습니다.
자바에서 데이터소스는 javax.sql.DataSource 인터페이스를 구현합니다. 이 데이터소스의 구현체는 JNDI 서비스에 등록되고, JNDI 이름을 사용하여 식별됩니다.
데이터소스를 통해 다음을 얻을 수 있습니다.
1. 커넥션 객체
2. 커넥션 풀에서 사용가능한 커넥션
3. 분산 트랜잭션과 커넥션 풀에서 사용가능한 커넥션
자바 설정으로 다음과 같이 만들 수 있습니다.
@Configuration
public class JpaConfig {
@Bean
public DataSource getDataSource() {
public DataSource dataSource() {
DataSource ds = new DataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost/spring5fs?characterEncoding=utf8");
ds.setUsername("id"); // id 설정
ds.setPassword("password"); // password 설정
ds.setInitialSize(2);
ds.setMaxActive(10);
return ds;
}
}
DriverClassName, Url, Username, Password 등 물리적 DB와 연결을 위한 기본 정보를 설정합니다.
미리 생성할 커넥션 개수를 initialSize로 지정합니다.
maxActive는 활성 상태가 가능한 최대 커넥션 개수를 지정합니다. 현재 활성 상태의 커넥션이 최대치라면 maxWait시간 만큼 대기하고 대기 시간 내에 풀에 반환된 커넥션이 없으면 Exception이 발생합니다.
* Connection Pool
커넥션풀(connection pool)이란, 미래의 데이터베이스에 요청이 올 때 다시 사용되는 데이터베이스 커넥션의 캐시입니다. 커넥션풀들은 전체적인 리소스 낭비를 줄일 수 있습니다.
커넥션 풀 관리가 중요한 이유는, 커넥션을 맺는 과정이 상당히 복잡하고 컴퓨터 자원을 많이 사용하기 때문입니다. Hikari는 미리 connection을 pool에 담아두고, 요청이 들어오면 Thread가 pool을 요청하고, Hikari는 Connection을 제공합니다.
Spring Boot 2.0버전부터는 Tomcat JDBC 대신에 Hikari를 사용하며 spring-boot-starter-data-jpa 와 spring-boot-starter-jdbc에 의존성이 포함되어 있습니다.
풀링 데이터 소스를 생성하기 위해 스프링 부트는 유효한 드라이버 클래스가 사용 가능한지 확인합니다.
spring.datasource.driver-class-name 속성이 설정되면, 설정된 드라이버 클래스가 로드됩니다.
- 자동 설정은 처음에 HikariCP을 확인하고 설정합니다.
- 사용하지 못한다면, Tomcat Pooling을 설정합니다
- 둘다 사용이 안된다면, Commons DBCP2를 확인합니다.
또한, JDBC가 궁금하다면 다음 글을 확인해주세요 ( 참고 )
다시 Hikari로 돌아와서 설정 방법 2가지를 알아보겠습니다.
1. application.properties, application.yml에서 설정하기
spring.datasource.hikari 접두사를 이용해서 속성들을 설정합니다.
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
...
2. Java에서 설정하기
#hikari.properties
driverClassName=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/testdb?useSSL=false
maximumPoolSize=20
username=testuser
password=test623
dataSource.cachePrepStmts=true
dataSource.prepStmtCacheSize=250
dataSource.prepStmtCacheSqlLimit=2048
properties를 가져와서 설정할 수도 있습니다.
@Configuration
public class AppConfig {
@Bean(destroyMethod = "close")
public DataSource dataSource() throws SQLException {
HikariConfig config = new HikariConfig("/hikari.properties");
HikariDataSource dataSource = new HikariDataSource(config);
return dataSource;
}
}
혹은 모든 속성을 직접 설정도 가능합니다.
@Bean(destroyMethod = "close")
public DataSource dataSource(){
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName("oracle.jdbc.driver.OracleDriver");
hikariConfig.setJdbcUrl("jdbc:oracle:thin:@ip:port:SID");
hikariConfig.setUsername("id");
hikariConfig.setPassword("password");
//hikariConfig.setMaximumPoolSize(5);
//hikariConfig.setConnectionTestQuery("SELECT 1");
//hikariConfig.setPoolName("springHikariCP");
HikariDataSource dataSource = new HikariDataSource(hikariConfig);
return dataSource;
}
*정리
Hikari는 이미 테스트를 통해 성능의 우수함이 증명되었습니다. 커넥션 풀의 등장배경과 역할, 효과를 먼저 확인하여
* 참고
https://jaehoney.tistory.com/33
https://howtodoinjava.com/spring-boot2/datasource-configuration/
https://gmlwjd9405.github.io/2018/05/15/setting-for-db-programming.html
https://www.geeksforgeeks.org/spring-jdbc-template/
https://yjh5369.tistory.com/entry/HikariCP-%EC%86%8C%EA%B0%9C
https://oingdaddy.tistory.com/13
https://zetcode.com/articles/hikaricp/
'학습 > DB' 카테고리의 다른 글
고급매핑 - 상속관계 (0) | 2022.07.07 |
---|---|
JDBC란? (0) | 2022.07.05 |
JPA를 이용해 페이징 만들기 (0) | 2021.12.15 |
JPA를 이용해 자동으로 시간, 작성자 추가하기 (1) | 2021.12.14 |
다형성 쿼리 (0) | 2021.10.07 |