크게 잡으면 좋을 것 같지만

동시 요청이 몰리면 커넥션 풀을 키우고 싶어진다. 대기가 줄어들 것 같기 때문이다. 하지만 대개 반대다.

풀 크기는 애플리케이션이 DB에 동시에 얼마나 많은 일을 시킬 것인가를 정하는 값이다. DB가 실제로 병렬 처리할 수 있는 양을 넘어서면, 넘긴 만큼은 DB 안에서 줄을 선다. 대기 장소가 애플리케이션에서 DB로 옮겨갔을 뿐이고, 그 과정에서 컨텍스트 스위칭과 락 경합이 늘어 오히려 느려진다.

DB가 동시에 할 수 있는 일의 양

DB의 병렬성은 대략 두 가지가 정한다.

HikariCP 문서가 제안하는 출발점은 이렇다.

connections = (core_count * 2) + effective_spindle_count

코어 8개에 SSD 한 대라면 열몇 개 남짓이다. 흔히 잡는 100보다 훨씬 작다.

Little’s Law로 가늠하기

대기 이론의 관계식 하나면 감을 잡을 수 있다.

L = λ × W
동시 처리 수 = 초당 처리 요청 수 × 요청당 소요 시간

초당 500건을 처리하고 쿼리 하나가 평균 10ms라면,

L = 500 × 0.01 = 5

이론상 커넥션 5개면 감당된다. 여유를 더해도 10~20 수준이다.

이 계산이 알려주는 것

식을 뒤집어 보면 더 중요한 사실이 나온다. W(쿼리 시간)를 줄이는 것이 L(풀 크기)을 늘리는 것보다 훨씬 강력하다. 쿼리를 10ms에서 2ms로 줄이면 같은 커넥션으로 다섯 배를 처리한다.

풀을 늘리고 싶어질 때는 보통 느린 쿼리가 원인이다. 풀 크기는 증상을 가리는 손잡이에 가깝다.

정리