Skip to content

TPS 설정 및 Hikari CP 커넥션 풀, 톰캣 설정

Kim Minjoo(김민주/리브) edited this page Oct 24, 2024 · 8 revisions

데벨업 팀은 첫 런칭 당시 우아한테크코스 7기 준비 오픈 카카오톡 채팅창의 참여자 약 300명이 모두 접속한다고 가정했습니다. 그리고 데벨업에서 가장 중요한 서비스이며 가장 많은 사용이 이루어질 것으로 예상되는 풀이 목록 조회를 기준으로 TPS를 측정했습니다. 풀이 목록 조회는 미션 태그와 해시태그를 이용한 검색이 가능하며 페이지네이션을 적용했으며 글을 작성한 회원, 관련 미션, 관련 해시 태그 등 여러 테이블을 JOIN한 데이터로 구성된 API입니다.

TPS가 최소 100은 되어야 유저가 많은 시간을 기다리지 않고 안정적으로 서비스를 사용할 수 있을 것이라고 가정했습니다.

Hikari CP 커넥션 풀이나 톰캣 관련 설정이 변경되어 WAS 서버를 새로 띄운 후 웜업을 한 뒤 성능 테스트를 진행했습니다. 성능 테스트는 Breakpoint Test를 사용해서 현재 인프라 상황에서 최대 TPS를 확인하고 부하 테스트를 통해 실제로 적정한 설정 값인지 확인 했습니다. 오류가 발생하지 않는 수준에서 TPS 수치와 JVM Heap 메모리 사용률, 서버 및 데이터베이스 CPU 사용률을 고려하여 적정한 설정 값을 찾았습니다.

Hikari CP 커넥션 풀과 톰캣 관련 설정을 조정한 후, 새로운 WAS 서버를 띄울 때마다 웜업을 먼저하고 본 성능 테스트를하는 방식으로 진행 했습니다. Breakpoint Test를 활용하여 현재 인프라 상황에서 최대 TPS를 측정하고, Load Test를 통해 실제 서비스 환경에서 적절한 설정 값을 검증했습니다. 이 과정에서 발생한 오류가 없는 범위 내에서 TPS 수치, JVM Heap 메모리 사용률, 서버 및 데이터베이스 CPU 사용률을 분석하여 최적의 설정 값을 도출했습니다.



  • TPS 측정 결과 표
Hikari CP 톰캣
threads
max
톰캣
max
connections
톰캣
accept count
TPS 최대 TPS
1 default default default 31.2 33
2 default default default 55.8 62.5
3 default default default 65.4 69
4 default default default 66.7 70.5
5 default default default 64.7 67.5
4 10 default default 66.4 69.5
4 20 default default 66.5 68.5
4 30 default default 64.9 68.5
4 100 default default 64.9 67.5
4 150 default default 66.2 69
4 175 default default 65.2 81.5
4 200 default default 62.4 66
4 250 default default 65 68
4 300 default default 64.5 70


여러 설정 값을 변경해가며 실험했지만 TPS가 60을 넘지 못하고 큰 변화를 보이지 않았습니다. 다양한 상황을 조합해본 결과, 데이터베이스가 병목 현상의 원인이라는 것을 발견했지만, DB 자체를 변경할 수 없는 상황이었습니다. 이에 따라 관련 쿼리 성능을 다시 분석하기로 결정했습니다.

데이터가 약 10만 건일 때, 기존 쿼리는 풀이 목록을 얻기 위해 6209.055 ms가 소요되었으며, API 응답 생성에는 8711 ms가 걸렸습니다. 기존 쿼리는 단일 쿼리이지만, 중복을 제거하기 위해 임시 테이블을 생성하고 제거하는 과정에서 상당한 시간이 소모되었습니다. 중복을 제거하지 않으면 데이터 중복(Data Duplication) 문제가 발생하기 때문에 이는 필수적인 과정이었습니다.

중복 제거를 위한 기존의 방법 대신, 필요한 디스커션 ID만 중복 제거하여 가져오고, 이후 필요한 모든 정보를 해당 ID를 통해 조회하는 방식으로 접근해 보자는 의견이 나왔습니다. 이를 적용한 결과, 수정된 쿼리는 정보를 얻기 위해 쿼리를 두 번 날리게 되었습니다. 그럼에도 불구하고 API 응답 시간은 8711 ms에서 2385 ms로 약 72.63% 감소했습니다. 단일 쿼리보다 유저에게 빠른 응답을 제공하는 것이 더 중요하다는 판단하에 쿼리를 변경했습니다.

또한, 실행 계획을 확인한 결과, 미션 해시 태그를 조회할 때 인덱스를 사용하지 않고 해시 조인을 수행하여 불필요하게 많은 행을 가져오는 문제가 있음을 발견했습니다. 이와 함께 ORDER BY 문에 사용되는 컬럼 또한 인덱스를 타지 않고 있었기에, 해당 컬럼에 대한 인덱스를 추가했습니다. 결과적으로, 조회 시간은 2808.89 ms에서 72.293 ms로 약 97.42% 감소했습니다.

쿼리 수정 후, 어떠한 조건도 변경하지 않았음에도 목표치인 TPS 100대를 달성했습니다. 이후 다양한 수치를 조금씩 변경해가며 성능을 확인한 결과, TPS는 큰 변화를 보이지 않았습니다. 그래프를 분석해본 결과, 성능 증폭이 심하지 않았던 두 실험은 첫 번째 실험(기본값)과 두 번째 실험(히카리 커넥션 풀 5)으로 나타났습니다.



실험 1 실험 2
image image
Hikari Connection Pool 기본 값 5
톰캣 threads max 기본 값 기본 값
톰캣 max connections 기본 값 기본 값
톰캣accept count 기본 값 기본 값
평균 TPS 112.6 110.9
최고 TPS 118 118
MTT 2,434.60 ms 2,477.78 ms
JVM Heap 메모리 사용률 69.98% 64.21%
WAS 서버 CPU 사용률 41% 44.2%
DB CPU 사용률 82%(최대 95.5%) 78.93%(최대 95.7%)


이 두 실험 간의 성능 차이가 미미해서, 더 적은 메모리와 데이터베이스 부하로 작동하는 두 번째 실험의 결과를 따라 히카리 커넥션 풀을 5로 조정하기로 결정했습니다.



Load Test 결과

image
항목 수치
Hikari Connection Pool 5
톰캣 threads max 기본 값
톰캣 max connections 기본 값
톰캣accept count 기본 값
평균 TPS 107.5
최고 TPS 137
MTT 2,790.88 ms
JVM Heap 메모리 사용률 64.63%
WAS 서버 CPU 사용률 39.4%
DB CPU 사용률 95.9%
Clone this wiki locally