티스토리 뷰

반응형

HikariCP

HikariCP(Hikari Connection Pool)

.

HikariCP 기본 설명은 쉽게 풀어서 설명된 링크를 참고해 보자.

.

최근 HikariCP Connection 관련 장애를 겪고, HikariCP 의 Connection 관련 이슈와 대응방법에 대하여 알아보게 되었다.

고로... 본문에는 Hikari 기본설정, Dead lock 과 해결방법에 대해서 간단하게 다뤄보려고 한다.

Hikari 기본설정

autoCommit

  • pool에서 반환된 connection의 기본 자동 커밋 동작 제어
  • Default: true

connectionTimeout

  • 클라이언트가 pool로부터의 연결을 기다리는 최대 시간
  • 연결을 사용할 수 없는 상태에서 이 시간이 초과되면 SQLException 발생
  • Lowest acceptable connection timeout: 250 ms
  • Default: 30000ms (30sec)

idleTimeout

  • Connection Pool 에서 쉬고 있는 커넥션을 유지하는 시간
  • minimumIdle(20) 이 maximumPoolSize(30) 보다 작게 설정되어 있을 때만 설정
    • default(10min) 가 적용될 경우 10분 동안 쉬고 있는 커넥션을 회수(단, 최소 minimumIdle 사이즈만큼은 유지)
  • default: 600000ms(10mi), 최솟값: 10000ms

keepaliveTime

  • HikariCP가 데이터베이스 또는 네트워크 인프라에 의해 시간 초과되는 것을 방지하기 위해 connection 유지를 위해 얼마나 자주 연결을 시도할 것인지 제어
  • maxLifetime 값보다 작아야 함. (connection이 살아있는지 확인하기 위해)
  • keepalive는 유휴 연결에서만 발생
  • connection이 keepalive 시간이 되면, connection은 pool에서 제거되고, pinged 된 후 다시 pool로 반환
  • The minimum allowed value: 30000ms (30sec)
  • Default: 0(비활성), 분 단위가 적절

maxLifetime

  • Connection Pool 에서 살아 있을 수 있는 커넥션의 최대 수명시간
  • 사용 중인 연결은 취소되지 않으며, 커넥션이 닫힌 후에만 제거
  • 풀 전체가 대상이 아닌 커넥션 별로 적용
    • Connection Pool 에서 대량으로 커넥션들이 제거되는 것을 방지하기 위함
  • 해당 옵션을 사용하는 것을 권장하고 database, infra 적용 Connection time limit 보다 작아야 함
  • 0으로 설정 시 infinite lifetime 적용
    • 단, idleTimeout 설정 시 적용 불가
  • default: 1800000ms (30min)

🔤 connectionTestQuery

  • Connection.isValid() API를 지원하지 않는 레거시 드라이버를 위한 설정
  • 드라이버가 JDBC4를 지원할 경우 설정하지 않는 것을 추천
  • 데이터베이스 연결이 활성 상태인지 확인하기 위해 풀에서 연결이 제공되기 직전에 실행되는 쿼리
  • Default: none

🔢 minimumIdle

  • 커넥션이 일을 하지 않아도 사이즈만큼은 커넥션 유지
  • 최적의 성능과 응답성을 요구한다면 default(same as maximumPoolSize) 사용

🔢 maximumPoolSize

  • Connection Pool 에 유지시킬 수 있는 최대 커넥션 수
  • Connection Pool 의 커넥션 수가 사이즈에 도달하게 되면 idle 상태는 존재하지 않음(default: 10)

🔤 poolName

  • Connection Pool 의 사용자 정의 이름
  • 로깅 및 JMX 관리 콘솔에서 식별
  • Default: auto-generated

Deadlock

부하 상황에서 Thread 간 Connection 을 차지를 하기 위한 Race Condition 발생

  • 하나의 트랜젝션에서 동시에 여러 Connection 을 사용할 경우, Connection 부족으로 HikariCP 에 대한 Thread 간 Dead lock 상태에 빠질 수 있다.

.

예를 들어보면..

Thread: 8개
HikariCP MaximumPoolSize: 5개
하나의 Task에서 동시에 요구되는 Connection 갯수: 2개

부하 상황에서 8개의 Thread 가 동시에 HikariCP 로부터 Connection 을 얻어내려 한다고 가정해 보자.

그렇다면 5개의 Thread 만이 Connection 을 가지고 Transaction 을 시작했을 것이다.

실행중인 Thread: 5개
대기중인 Thread: 3개

사용중인 Connection: 5개
Connection 대기중(handOffQueue): 3개

.

하지만 트랜잭션 내에서 추가의 Connection 이 필요할 경우, 현재 Pool 에는 idle Connection 이 없기 때문에 handOffQueue 에서 5개의 Thread 가 추가로 대기하고 있게 될 것이다.

실행중인 Thread: 5개
대기중인 Thread: 3개

사용중인 Connection: 5개
Connection 대기중(handOffQueue): 3+5개

.

connectionTimeout 만큼의 시간이 흐르고.. 그렇게 Connection Timeout 으로 아래 에러가 발생하고..

HikariPool-1 - Connection is not available, request timed out after

SQLTransientConnectionException 으로 인해 Transaction rollback 되면서 다시 Connection 이 Pool에 반납되고 handOffQueue 에서 기다리는 다른 Thread 에서 다시 Connection 을 받아가기 시작하게 된다..

Solution

maximumPoolSize

유지시킬 수 있는 최대 커넥션 수를 증가시키는 방법

maximumPoolSize = Tn x (Cm - 1) + 1
Tn : 전체 Thread 갯수(8)
Cm : 하나의 Task에서 동시에 필요한 Connection 수(2)
maximumPoolSize = 9

HikariCP wiki에서는 이 공식대로 Maximum pool size 를 설정하면 Dead lock을 피할 수 있다고 한다.

.

기본 공식을 확장시킨 공식을 활용하면 아래와 같이 설정도 가능하다.

maximumPoolSize = Tn x (Cm - 1) + (Tn / 2)
Tn : 전체 Thread 갯수(8)
Cm : 하나의 Task에서 동시에 필요한 Connection 수(2)
maximumPoolSize = 12

.

유지시킬 수 있는 최대 커넥션 수를 증가시키는 방법은 단순한 방법이지만, 만능이라고 할 수는 없다.

트래픽이 증가한다면.. 결국 커넥션이 금방 고갈될 것이다.

connectionTimeout

연결을 기다리는 최대 시간을 증가시키는 방법

클라이언트가 응답을 위해 대기하는 시간이 길어지는 게 좋은 것일까 싶긴 하다..

maximumPoolSize 와 적절하게 맞춰주는 게 중요할 것이라고 생각된다.

Nested Transaction

중첩 트랜젝션을 사용하지 않는 방법

중첩 트랜젝션 사용 시, 서브 트랜젝션의 작업이 완료될 때까지 커넥션을 점유하고 있기 때문에

dead lock 을 유발시킬 수 있는 가능성이 높아진다.

Reference

HikariCP Dead lock 이론: https://techblog.woowahan.com/2664/

HikariCP Dead lock 대처: https://techblog.woowahan.com/2663/

.

제가 잘못 알고 있는 부분이 있다면 달콤한 피드백 부탁드립니다..🙏🏻

반응형

'Web > Infra' 카테고리의 다른 글

[Infra] 11st MSA  (0) 2023.11.19
[AWS EC2] Nginx in Docker 무중단 배포  (0) 2023.11.07
[AWS EC2] Jenkins in Docker 배포 자동화 구축  (0) 2023.11.05
[AWS] AWS EC2 & RDS Free Tier 구축  (0) 2023.11.04
Firebase & Spring-boot 연동  (0) 2023.09.24
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday