[Spring Boot] Hikari CP 커스텀으로 성능 최적화하기

이동엽·2023년 8월 16일
2

spring

목록 보기
10/16
post-thumbnail

Hikari CP란?

: 데이터베이스 연결(Connection)을 관리해 주는 도구(라이브러리)

: 커넥션 풀(Connection Pool)이 설정된 커넥션의 사이즈만큼의 연결을 허용하며 HTTP 요청에 대해 순차적으로 DB 커넥션을 처리해 주는 기능을 수행


스프링에서의 커넥션 풀

자바에서는?
→ 기본적으로 DataSource 인터페이스를 사용하여 커넥션풀을 관리한다.

그럼 Spring에서는?
→ 사용자가 직접 커넥션을 관리할 필요없이 자동화된 기법들을 제공하는데, SpringBoot 2.0 이전에는 tomcat-jdbc를 사용하다가 2.0이후 부터는 HikariCP를 기본옵션으로 채택 하고있다.


히카리 벤치마킹 페이지를 참고하면 성능이 월등한 것을 확인 할 수 있다.


Database Connection Pool( : DBCP)

: 최초 풀에서 생긴 연결들로 요청을 처리하고, 이를 재 사용하는 것을 의미


데이터베이스 커넥션 풀을 사용하는 이유

JDBC 연결은 드라이버를 로드하고 연결하여 객체를 받아와야 하는 과정을 가지고 있다.

이 과정은 매번 사용자가 요청할 때마다 드라이버를 로드하고 커넥션 객체를 생성하여 연결하고 종료하는 과정이 불편하고 속도와 자원 소모에 대한 단점이 있다.

→ 이를 보완하기 위해 데이터베이스 커넥션 풀을 사용!



데이터베이스 커넥션 풀의 과정

  1. WAS가 실행 되면서 Pool 내에 Connection들을 생성
  2. HTTP의 요청이 올 때, Pool 내에서 Connection 객체를 가져다가 사용
  3. 사용이 완료된 Connection 객체는 Pool 내에 반환


데이터베이스 커넥션 풀의 장점

  1. WAS와 데이터베이스와의 연결을 정해놓은 만큼만 미리하여, 매번 생성하는 비용을 줄일 수 있다.
  2. Connection에 대해 조정을 할 수 있다.
    • 커넥션 풀을 크게 설정하면? → 메모리 소모가 큰 대신 많은 사람의 대기시간이 줄어 듬
    • 커넥션 풀을 작게 설정하면? → 사용자의 대기시간이 길어짐


데드락 피하기

커넥션 풀 사이즈를 지정할 때는 항상 데드락을 고려해야 한다.
우아한 형제들에서 제시한 이론적으로 필요한 최소한의 커넥션 풀 사이즈는 다음과 같다.

PoolSize = Tn × ( Cm -1 ) + 1

  • Tn : 전체 Thread 갯수
  • Cm : 하나의 Task에서 동시에 필요한 Connection 수

→ 이 경우는 데드락은 피할 수 있지만, 여유 커넥션이 +1 개 이므로 성능상 좋지 못할 수 있다.

커넥션 풀에 더욱 여유를 주고 싶다면 아래와 같이 해보자.

PoolSize = Tn × ( Cm - 1 ) + ( Tn / 2 )

  • thread count : 16
  • simultaneous connection count : 2
  • pool size : 16 * ( 2 – 1 ) + (16 / 2) = 24


환경 설정

  1. 의존성 추가
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
}

  1. 설정 추가
@Configuration
public class MyDataSourceConfiguration  {

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.hikari")
    public HikariDataSource dataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }
}

  1. property 정의
spring:
  datasource:
    url: //url
    username: //username
    password: //passowrd
    driver-class-name: //driver
    **hikari:
      connection-timeout: 3000
      validation-timeout: 3000
      minimum-idle: 5
      max-lifetime: 240000
      maximum-pool-size: 20**

위에서 설정 예시들은 아래와 같다.

  • maximum-pool-size: 최대 pool size (defailt 10)
  • connection-timeout: 커넥션의 타임아웃
  • validation-timeout: 유효한 타임아웃
  • minimum-idle: 연결 풀에서 HikariCP가 유지 관리하는 최소 유휴 연결 수
  • idle-timeout: 연결을 위한 최대 유휴 시간
  • max-lifetime: 닫힌 후 pool 에있는 connection의 최대 수명 (ms)입니다.
  • auto-commit: auto commit 여부 (default true)

  1. Hikari Pool이 제대로 동작하고 있는지 로깅 레벨 설정
logging:
  level:
    org.hibernate.SQL: info
    root: info
    com.zaxxer.hikari.pool.HikariPool: debug

  1. 실행 결과

profile
백엔드 개발자로 등 따숩고 배 부르게 되는 그 날까지

2개의 댓글

comment-user-thumbnail
2023년 8월 16일

공감하며 읽었습니다. 좋은 글 감사드립니다.

답글 달기
comment-user-thumbnail
2024년 1월 25일

@ConfigurationProperties("spring.datasource.hikari")
해당 어노테이션 사용한 부분에 DataSourceProperties 객체에 Hikari 옵션 설정값이 들어갈 수가 있나요?
해보니까 전부 Default 값으로 binding 되는데 이런 문제는 없으셨는지 여쭙니다

답글 달기