이번 포스팅에선 서비스 사용자 수를 늘리기 위해 새로 개발한 분석 기능에 대한 성능 테스트(Performance Testing) 이야기를 담아보려 합니다.
유저가 작성한 글을 기반으로 하는 신규 기능은 3가지입니다.
- 데일리 리포트 또는 위클리 리포트를 받아볼 수 있는 날짜들을 조회하는 API
- 리포트를 생성 요청하는 API
- 날짜별로 생성된 리포트들을 조회하는 API
이 기능들 가운데 외부 API를 사용하는 2번을 제외한 1번과 3번 조회 관련 API가 많이 사용될 것으로 예상됩니다.
그래서 조회 API들에 대해 서비스가 예상되는 트래픽에서 얼마나 빠르고 안정적으로 응답하는지, 짧은 시간에 급격하게 몰리는 트래픽을 얼마나 견딜 수 있는지를 검증하기 위해 성능 테스트를 수행할 필요가 있습니다.
어떤 테스트를 할 것인가?
성능 테스트에는
- 얼마나 빨리 응답할 수 있는지
- 얼마나 많은 사용자를 처리할 수 있는지
- 스트레스 상황에서 얼마나 안정적인지
등 테스트 목적에 따라 `부하 테스트`, `스트레스 테스트`, `스파이크 테스트` 등이 있는데요,
조회 API가 얼마나 빠르고 안정적인지, 급격한 트래픽을 어느 정도까지 견딜 수 있는지를 검증하기 위해 `부하 테스트`와 `스파이크 테스트`를 수행하기로 결정했습니다.
현재 서버의 자원 사용률은 얼마인가?
현재 Ncloud를 활용한 서버는 CPU 코어가 2개, 메모리는 8GB 정도인데요,
서버에서 cpu 사용률, 메모리 사용률, 그리고 컨테이너의 자원 사용률을 조사해 봤습니다.
가장 작은 스펙의 서버인 데다 APM 툴과 함께 구성되어 있어서 사용할 수 있는 메모리가 2.4GB 정도로 여유롭진 않은 상황입니다.
일반적인 상황에서 성능 지표
운영 서버와 동일한 스펙의 개발 서버(CPU 2 core, Memory 8gb)에서 진행했으며, 테스트 툴은 JMeter를 이용했습니다.
JMeter 설정은 아래에 작성된 것처럼 실제 서비스 인원 수와 예상되는 패턴으로 테스트를 진행했습니다.
- Thread 개수: 현재 가입자 수 100여 명 => 100개
- Ramp-up 시간: 10초 동안 증가
- 루프 카운트: 5번 반복 요청
이론상 최대 TPS는 50 TPS (= 100 * 5 / 10)입니다.
(TPS = 전체 요청 수 / 활동 시간(초) = 동시 접속자 수 * 반복 요청 수 / 활동 시간(초))
아래는 테스트 결과입니다.
라벨 | 표본 수 | 평균 | 최소값 | 최대값 | 표준편차 | 오류 % | 처리량 | 수신 KB/초 | 전송 KB/초 | 평균 바이트 수 |
생성 가능 일자 조회 (데일리 리포트) |
500 | 20 | 10 | 100 | 9.81 | 0.000% | 49.36321 | 124.48 | 13.26 | 2582.2 |
생성 가능 일자 조회 (위클리 리포트) |
500 | 16 | 9 | 37 | 4.40 | 0.000% | 49.79088 | 56.38 | 13.42 | 1159.5 |
데일리 리포트 조회 | 500 | 19 | 11 | 41 | 5.36 | 0.000% | 49.80080 | 39.79 | 12.99 | 818.1 |
총계 | 1500 | 19 | 9 | 100 | 7.14 | 0.000% | 147.69594 | 219.23 | 39.33 | 1519.9 |
조회 API 3개에 대해 간략하게 요약하면 아래와 같습니다. (`connection time out` 200ms, `read time out` 250ms 기준)
- 최대 응답속도 100ms (데일리 리포트 생성 가능 일자 조회)
- 평균 응답속도 19ms
- 처리량: 평균 49.6 TPS
- 오류율: 0%
처리량과 응답 속도, 에러율 모두 준수한 성능으로 보입니다.
성능 테스트 계획하기
이제 성능 테스트를 계획해 보겠습니다.
부하 테스트
평소보다 트래픽이 10배 증가함을 가정하고 작성한 부하 테스트 시나리오입니다.
- 예상 트래픽:
- 목표 TPS: 500 TPS (=100 * 5 * 10 / 10)
- 평균 응답 시간: 300ms 이내
- 오류율: 1% 이내
- 시스템이 다운되지 않을 것
현재 시스템에서 테스트한 결과는 아래와 같습니다.
라벨 | 표본 수 | 평균 | 최소값 | 최대값 | 표준편차 | 오류 % | 처리량 |
생성 가능 일자 조회 (데일리 리포트) |
5000 | 351 | 17 | 500 | 48.13 | 96.340% | 423.51347 |
생성 가능 일자 조회 (위클리 리포트) |
5000 | 348 | 327 | 483 | 19.76 | 100.000% | 421.86973 |
데일리 리포트 조회 | 5000 | 359 | 327 | 579 | 40.92 | 100.000% | 427.31390 |
총계 | 15000 | 353 | 17 | 579 | 38.50 | 98.780% | 283.02955 |
간략하게 요약하면,
- 최대 응답속도 579ms (데일리 리포트 생성 가능 일자 조회)
- 평균 응답속도 351ms
- 처리량: 평균 423 TPS
- 오류율: 98% (read time out 오류)
- 시스템은 다운되지 않음
오류율이 98%이면서 평균 423 TPS 정도입니다.
데이터베이스 - 커넥션 확인
grafana를 이용한 데이터베이스 전체 커넥션을 보면, 최대 117개의 요청에서 커넥션 획득을 위해 지연된 것을 확인할 수 있습니다.
(참고로 그래프에서 보실 수 있듯이 MySQL은 최대 커넥션 수가 150개, Spring은 hikaricp 커넥션 풀 수가 기본값으로 10개입니다.)
데이터베이스 - 커넥션 사용 시간, 커넥션 획득 시간 확인
커넥션 사용 시간은 부하가 걸리는 구간에서 50.5ms 안으로 기록되었습니다.
커넥션 획득 시간(커넥션을 획득하는 데 걸린 시간)은 위에서 설명한 커넥션 획득 지연 개수가 최대 117개인 수치와 함께 봐야 합니다.
부하가 걸릴 때 최대 800ms 정도로 올라갔다가 테스트가 끝난 뒤에도 700ms 유지되고 있습니다.
이 부분도 해결이 필요해 보입니다.
스파이크 테스트
1초 이내 `순간 트래픽`이 10배 증가함을 가정한 스파이크 테스트 시나리오입니다.
- 예상 트래픽:
- 목표 TPS: 5,000 TPS (=1,000 * 5 / 1)
- 응답 속도는 늦어도 2,000ms (2초) 내
- 1초 이내에 TPS 5,000까지 급격히 증가
- 오류율: 5% 이내
현재 시스템에서 테스트한 결과는 아래와 같습니다.
라벨 | 표본 수 | 평균 | 최소값 | 최대값 | 표준편차 | 오류 % | 처리량 |
생성 가능 일자 조회 (데일리 리포트) |
1000 | 1605 | 51 | 2719 | 849.00 | 57.600% | 283.28612 |
생성 가능 일자 조회 (위클리 리포트) |
1000 | 1121 | 0 | 2148 | 971.76 | 94.000% | 180.31013 |
데일리 리포트 조회 | 1000 | 1467 | 0 | 2150 | 897.93 | 98.900% | 132.81976 |
총계 | 3000 | 1397 | 0 | 2719 | 930.17 | 83.500% | 393.28789 |
스파이크 테스트도 간략하게 요약하면,
- 최대 응답속도 2719ms (데일리 리포트 생성 가능 일자 조회)
- 평균 응답속도 1397ms
- 처리량: 평균 198 TPS
- 오류율: 83.5% (read time out 오류)
- 시스템은 다운되지 않음
오류율이 83.5%이면서 평균 198 TPS 정도입니다.
- 이론상 최대 TPS는 5,000 TPS이지만 시스템의 한계상 `포화 지점(Saturation Point)`에 도달하면 처리량이 늦어져 특정 값으로 수렴할 것 같습니다.
- `포화 지점(Saturation Point)`: 시스템의 한계로 인해 처리량이 더 이상 늘지 않고 일정한 값에 수렴하는 지점
다음 포스팅에선 응답 속도와 TPS를 개선하는 과정을 다루겠습니다.
읽어주셔서 감사합니다.
참고
'Project' 카테고리의 다른 글
[포텐데이 409-1pick] 신규 분석 기능 성능 테스트 (3) (1) | 2024.12.08 |
---|---|
[포텐데이 409-1pick] 신규 분석 기능 성능 테스트 (2) (0) | 2024.12.06 |
[포텐데이 409-1pick] 분석 서비스 개발 중 만난 데드락과 동시성 문제 해결기 (5) (0) | 2024.11.28 |
올려 올려 라디오 NCloud 활용 후기 (2) | 2024.11.27 |
[포텐데이 409-1pick] 분석 서비스 개발 중 만난 데드락과 동시성 문제 해결기 (4) (2) | 2024.11.27 |