토이 프로젝트의 핵심 기능 개발이 거의 완료되면서, 서버 설정의 다양한 변화가 시스템 성능에 어떤 영향을 미칠지에 대한 호기심이 생겼습니다. 구체적으로, 요청을 처리하는 쓰레드의 수, 웹 애플리케이션 서버(WAS)의 구성 변화(단일 서버 대비 다중 서버 구성), 그리고 데이터베이스 커넥션 풀 조정이 서버의 처리 능력에 어떠한 차이를 가져오는지 직접 확인하고 싶었습니다. 이번 포스팅에서는 스트레스 테스팅 도구 nGrinder를 활용하여 여러 설정 변화가 실제 성능에 미치는 영향을 간단히 알아보겠습니다.
nGrinder를 설치하는 방법은 이미 많은 글들이 있으므로 다루지 않습니다.
성능 테스트 보고서 등장하는 핵심 용어를 정리해 보겠습니다.
항목 | 설명 |
---|---|
총 Vuser | 동시에 시스템에 요청을 보내는 가상 사용자의 수 |
TPS | Transactions Per Second, 초당 처리할 수 있는 트랜잭션의 수 |
최고 TPS | 테스트 기간 동안 서버가 처리한 최대 초당 트랜잭션 수 |
평균 테스트 시간 | 서버가 요청에 대해 응답하는 데 걸리는 평균 시간 |
총 실행 테스트 | 테스트 동안 실행된 총 트랜잭션의 수 |
성공한 테스트 | 테스트 중 성공적으로 완료된 트랜잭션의 수 |
에러 | 테스트 동안 발생한 에러의 수 |
동작 시간 | 테스트가 수행된 총 시간 |
TPS가 높을수록 시스템이 더 많은 요청을 빠르게 처리할 수 있다는 것을 의미합니다. 이제, 다양한 서버 설정 변경을 통해 TPS가 어떻게 달라지는지 살펴보겠습니다.
가장 먼저 실험해 볼 것은, WAS가 1대, 커넥션 풀이 10개일 때 쓰레드 변화에 따른 TPS 변화를 알아보겠습니다.
단일 쓰레드의 부하 테스트를 진행해 보았습니다. TPS는 17.2가 나왔네요.
Vuser | TPS | 최고 TPS | 평균 테스트 시간(ms) | 총 실행 테스트 | 성공한 테스트 | 에러 | 동작 시간 |
---|---|---|---|---|---|---|---|
1 | 17.2 | 18.5 | 55.45 | 484 | 484 | 0 | 00:00:30 |
AWS t2.micro
인스턴스의 CPU 사용량은 26%까지 상승했습니다.
쓰레드의 수를 5개로 증가시킨 결과, TPS는 89.3으로 크게 향상 되었습니다.
Vuser | TPS | 최고 TPS | 평균 테스트 시간(ms) | 총 실행 테스트 | 성공한 테스트 | 에러 | 동작 시간 |
---|---|---|---|---|---|---|---|
5 | 89.3 | 95.5 | 54.14 | 2,508 | 2,508 | 0 | 00:00:30 |
CPU 사용률은 56.6%로 측정되어 안정적입니다.
쓰레드를 10개로 늘려서 테스트를 해 본 결과, TPS는 114.1로 증가했으나 평균 테스트 시간이 약간 증가했습니다.
Vuser | TPS | 최고 TPS | 평균 테스트 시간(ms) | 총 실행 테스트 | 성공한 테스트 | 에러 | 동작 시간 |
---|---|---|---|---|---|---|---|
10 | 114.1 | 158.5 | 78.83 | 3,202 | 3,202 | 0 | 00:00:31 |
CPU 사용률이 86.7%로 상승하여 시스템의 부하가 증가했음을 알 수 있습니다.
쓰레드 15개 까지 늘렸을 때, 여전히 부하를 견디며 TPS는 130.6으로 증가했습니다. 하지만 평균 테스트 시간이 증가하고 1건의 에러가 발생하였습니다.
Vuser | TPS | 최고 TPS | 평균 테스트 시간(ms) | 총 실행 테스트 | 성공한 테스트 | 에러 | 동작 시간 |
---|---|---|---|---|---|---|---|
15 | 130.6 | 200.0 | 103.25 | 3,403 | 3,402 | 1 | 00:00:30 |
CPU 사용률은 91.1%로 성능의 한계가 오는 것 같습니다.
쓰레드를 20개로 설정했더니, TPS는 오히려 114.7로 감소하였고, 평균 테스트 시간도 증가하였습니다.
Vuser | TPS | 최고 TPS | 평균 테스트 시간(ms) | 총 실행 테스트 | 성공한 테스트 | 에러 | 동작 시간 |
---|---|---|---|---|---|---|---|
20 | 114.7 | 227.0 | 143.41 | 3,221 | 3,221 | 0 | 00:00:30 |
CPU 사용률이 100%에 달하여 시스템의 한계에 도달하였습니다.
쓰레드 수가 증가함에 따라 TPS가 향상되는 것을 보았으나 일정 수준 이상에서는 오히려 성능이 저하되거나 시스템의 한계에 이를 수 있음을 확인했습니다.
쓰레드 섹션에서의 실험 결과, 쓰레드 수를 10개 혹은 15개로 설정하는 것이 적절해 보입니다. 이제 커넥션 풀을 고려해 보겠습니다. 스프링 부트 애플리케이션에서 사용하는 히카리CP의 기본 커넥션 풀 설정이 10개인 상황에서 15개의 쓰레드가 동시에 요청을 처리할 경우, 5개의 요청은 커넥션을 기다리는 Pending 상태에 놓이게 됩니다.
쓰레드 개수를 30개로 늘려 테스트했을 때, APM 툴을 통해 커넥션 풀에서 15개의 Pending 상태인 커넥션을 확인할 수 있었습니다.
이번에는 커넥션 풀의 크기를 조정하며 TPS가 어떻게 변화하는지 테스트해 보겠습니다.
쓰레드 섹션에서 쓰레드 수 15개에 커넥션 풀이 10개일 때의 테스트에서는 TPS가 130.6으로 나타났지만, 매 번 똑같은 TPS를 보장하지는 않습니다.
아래의 결과를 보면 재 테스트 시 TPS는 118.1로 감소했습니다. 이는 네트워크 지연, GC 등의 여러 요인에 의한 성능 변화가 있을 수 있으므로 좀 더 확실한 TPS를 측정하려면 많은 시행 횟수를 통하여 평균값을 측정하는 것이 타당해 보입니다.
Vuser | TPS | 최고 TPS | 평균 테스트 시간(ms) | 총 실행 테스트 | 성공한 테스트 | 에러 | 동작 시간 |
---|---|---|---|---|---|---|---|
15 | 118.1 | 300.0 | 105.14 | 3,315 | 3,315 | 0 | 00:00:31 |
커넥션 풀을 쓰레드 수와 동일하게 15개로 늘렸을 때, 이론적으로는 모든 쓰레드가 커넥션을 받을 수 있으므로 TPS가 크게 상승할 것으로 기대하였습니다. 그러나 실제 TPS는 127.8로, 소폭 상승하긴 했지만 쓰레드 섹션의 15개 테스트보다는 낮은 수치를 보였습니다.
Vuser | TPS | 최고 TPS | 평균 테스트 시간(ms) | 총 실행 테스트 | 성공한 테스트 | 에러 | 동작 시간 |
---|---|---|---|---|---|---|---|
15 | 127.8 | 223.5 | 95.31 | 3,587 | 3,587 | 0 | 00:00:30 |
커넥션 풀의 크기를 쓰레드 수에 맞춰 증가시켰을 때, 예상과는 달리 TPS는 소폭 상승했습니다. 즉 커넥션 풀의 크기를 증가시키는 것이 항상 성능 향상으로 이어지지 않을 수 있습니다.
마지막으로 WAS를 2대로 늘려보겠습니다. WAS는 독립적인 커넥션 풀을 유지하므로, 전체적으로는 커넥션 풀이 두 배로 증가 합니다. 따라서 커넥션 풀은 10개로 변경하겠습니다.
TPS는 121.1로 WAS가 1대일 때와 별 차이가 없습니다.
Vuser | TPS | 최고 TPS | 평균 테스트 시간(ms) | 총 실행 테스트 | 성공한 테스트 | 에러 | 동작 시간 |
---|---|---|---|---|---|---|---|
15 | 121.1 | 180.5 | 120.58 | 3,400 | 3,400 | 0 | 00:00:30 |
CPU 사용률을 확인해 보니 100%로 커넥션 풀 섹션과 동일하게 외부 요인에 영향을 받은 것 같습니다.
이번에는 쓰레드를 10개로 줄여서 테스트 해 보겠습니다.
TPS는 122.3으로 WAS가 1대일 때의 TPS인 114.1 보다 소폭 증가했습니다.
Vuser | TPS | 최고 TPS | 평균 테스트 시간(ms) | 총 실행 테스트 | 성공한 테스트 | 에러 | 동작 시간 |
---|---|---|---|---|---|---|---|
10 | 122.3 | 175.5 | 75.52 | 3,433 | 3,433 | 0 | 00:00:30 |
쓰레드가 10개일 때 상황을 보면 WAS 인스턴스의 수를 조정하면 시스템의 처리량을 향상시킬 수 있으나, 쓰레드가 15개 일때의 상황을 보면 오히려 자원의 과도한 사용에 따라 처리량이 감소될 수 있다는 것을 확인할 수 있습니다.
성능 테스트의 결과를 종합해보면, 쓰레드 수, 커넥션 풀 크기, WAS 인스턴스의 수를 조정하여 시스템의 처리량을 향상시킬 수 있는 가능성을 확인했습니다. 그러나 이러한 설정 변경들이 항상 선형적인 성능 향상을 보장하지는 않는다는 것을 알게 되었습니다.
이번에 nGrinder를 이용한 부하 테스트를 진행하면서 많은 활용을 할 수 있겠다는 생각이 들었는데요. 개발을 하다보면 '캐시, 쿼리 튜닝 등을 이용한 성능 향상이 되었음을 어떻게 확인해 볼까?'라는 생각이 들 때가 있습니다. 이 때, 개선 전후의 TPS를 비교함으로써 조금 더 구체적인 수치를 알 수 있을 것 같습니다.
감사합니다!