Hikari Connection Pool에 대하여 (1)

na.ram·2025년 5월 11일

Spring

목록 보기
6/13
post-thumbnail

🔎 Connection Pool?

데이터베이스와 어플리케이션을 연결하는 과정은 굉장히 비용이 많이 듭니다. 이런 비용을 줄이기 위해 Connection Pool의 개념이 등장하게 되었습니다.

먼저 Connection Pool에 데이터베이스에 연결된 객체들을 생성해둔 다음에 요청이 들어오면 Connection Pool에 존재하는 Connection 객체를 주고, 다 사용하면 Connection Pool에 반환하게 됩니다.

이를 통해 매번 데이터베이스와 연결하기 위해 Connection을 만들고, 끊는 비용을 아낄 수 있고, 효율적으로 데이터베이스와의 연결을 관리할 수 있습니다.

Connection Pool은 HikariCP, Tomcat pooling DataSource, Commons DBCP2, Oracle UCP 등 다양하지만, Spring Boot의 경우, 2.0부터는 HikariCP를 사용하고 있습니다.
아래의 사진에서 보이듯 성능 상의 이유가 아닐까 싶습니다.

(2.0 이전에는 Tomcat pooling DataSource를 기본적으로 사용했습니다.)


🔎 HikariCP Configuration?

yaml에서도 설정할 수 있으며, 설정 가능한 옵션들은 아래와 같습니다.

auto-commit

풀에 반환된 커넥션의 기본 auto-commit 동작을 제어합니다.
기본값은 true입니다.

connection-timeout

HikariCP로부터 커넥션을 받기 위해 대기하는 최대 시간(밀리초)으로, 이 시간을 초과하게 되면 SQLException이 발생합니다.
허용되는 최솟값은 250, 기본값은 30000(30초)입니다.

idle-timeout

각 커넥션이 유휴 상태로 유지되도록 허용하는 최대 시간(밀리초)으로, 이 옵션은 minimum-idlemaximum-pool-size보다 작게 설정된 경우에만 적용됩니다.
만약 값이 0일 경우에는 유휴 커넥션이 풀에서 제거되지 않음을 의미합니다.
허용되는 최솟값은 10000, 기본값은 600000(10분)입니다.

keepalive-time

데이터베이스 또는 네트워크 인프라에 의한 타임 아웃을 방지하기 위해 HikariCP가 커넥션을 활성 상태로 유지하려고 시도하는 빈도로, 이 값은 max-lifetime보다 작아야만 합니다.
허용되는 최솟값은 30000, 기본값은 120000(2분)입니다. (분 단위의 값을 추천)

max-lifetime

풀 안의 커넥션의 최대 생존 시간으로, 사용중인 커넥션은 절대 제거되지 않고, 닫힐 때에만 제거됩니다.
이 값을 설정하는 것이 강력히 권장되며, 데이터베이스 또는 인프라에 부과된 연결 시간 제한보다 몇 초 단축되어야 합니다.
값을 0으로 설정하면 최대 수명이 없음(무한한 수명)을 나타내며 이는 idle-timeout 설정에 따라 달라질 수 있습니다.
허용되는 최솟값은 30000, default 1800000(30분)입니다.

minimum-idle

HikariCP가 풀에 유지하려고 하는 유휴 커넥션의 최소 수로, 유휴 커넥션이 이 값 아래로 떨어지고, 풀 내의 총 커넥션이 maximum-pool-size보다 적다면 HikariCP는 추가적인 커넥션을 빠르고, 효율적으로 추가하기 위해 최선을 다할 것입니다.
그러나 스파이크 수요에 대한 최대 성능과 응답성을 위해 이 값을 설정하지 않고, HikariCP가 고정 크기 커넥션 풀로 동작하도록 두는 것이 좋습니다.
기본값은 maximum-pool-size와 동일합니다.

maximum-pool-size

유휴 커넥션과 사용 중인 커넥션 모두를 포함하여 풀이 도달할 수 있는 최대 사이즈로, 기본적으로 이 값은 데이터베이스 백엔드에 실제 연결의 최대 수를 결정합니다.
풀이 이 사이즈에 도달하고, 사용 가능한 유휴 커넥션이 없다면 getConnection()을 통한 커넥션 연결은 최대 connection-timeout 밀리초 동안 대기하다 시간이 초과되면 예외가 발생합니다.
기본값은 10입니다.

pool size 공식

이 블럭은 HikariCP의 About Pool Sizing의 번역입니다.

최적의 처리량을 얻기 위해 동시 활성 커넥션 수는 아래 공식을 통해 도출된 값의 근처여야 합니다.
(이 공식이 SSD에 얼마나 잘 적용되는지는 아직 분석되지 않았습니다.)

connections = ((core_count * 2) + effective_spindle_count)
core_count : 하이퍼스레딩(HT)가 활성화되어 있더라도 논리 쓰레드를 포함하지 않고, 실제 물리 코어만 계산
effective_spindle_count : DB 서버가 관리할 수 있는 동시 I/O 요청의 개수

만약 4코어 i7 서버에 하드 디스크가 하나 있다고 가정했을 때에는
공식을 통해 도출된 값(9 = ((4 * 2) + 1)의 근처인 10 정도로 설정하는 것이 적당합니다.

이 구성으로도 단순 쿼리를 수행하는 프론트엔드 사용자 3000명이 초당 6000 트랜잭션 (6000 TPS)을 처리할 수 있을 것이라 예상합니다.

만약 커넥션 풀 크기를 이보다 훨씬 초과한 값으로 설정한다면 TPS는 점점 떨어지고, 프론트엔드 응답 시간은 증가하게 될 것입니다.

잘 튜닝된 커넥션 풀은 1. 데이터베이스가 동시에 처리할 수 있는 쿼리 수의 한계에 딱 맞춰져 있어야 하며, 2. 이 한계는 대부분의 경우, 위에서 언급된 (CPU 코어 수 * 2) 수준을 넘지 않습니다.

명제
커넥션을 기다리는 쓰레드로 포화된 작은 풀이 이상적입니다.
→ 커넥션을 기다리는 쓰레드가 많은 상태가 바람직합니다.

0개의 댓글