전체 데이터 조회 성능 테스트 기록

박준수·2023년 5월 7일
0

[성능테스트]

목록 보기
1/4

성능테스트를 하기 위해 K6를 적용한 이유

  1. 부하테스트 : k6은 애플리케이션에 대한 부하를 시뮬레이션하고 이를 통해 애플리케이션의 성능과 안정성을 평가할 수 있습니다.
  2. 확장성: k6은 클라우드 기반으로 구축되어 있으므로, 사용자 수가 증가함에 따라 애플리케이션의 성능을 테스트하는 데 적합합니다. (Vus 설정가능)
  3. 실시간 모니터링: k6은 실시간으로 애플리케이션의 성능을 모니터링하고 결과를 시각화하여 분석할 수 있습니다. (Influxdb 와 Gragfana로 시각화)
  4. 쉬운 사용: k6은 간단하고 직관적인 명령어를 제공하여 사용자가 쉽게 성능 테스트를 수행할 수 있습니다. ( Javascprit언어로 script파일 작성 )

Pagination이 필요한 이유

pagination을 적용 전

전체 상품 검색 API를 구현하고 데이터 베이스에 50만 데이터를 넣어 latency를 확인해 보았습니다. 50만 데이터를 전체 반환하니 2m 26.68s라는 굉장한 시간이 걸렸습니다.

pagination을 적용후

pagination을 적용후 한 페이지당 데이터의 반환 개수를 80개로 하니 131ms로 줄어들었습니다.

(한 페이지당 latency는 약 백 중반 ~ 2백 중반ms)

pagination을 왜 이용해야할까?

  • 페이지 번호와 함께 인덱스를 사용하면, SQL 쿼리에서 LIMIT 및 OFFSET을 사용하여 현재 페이지에 표시되는 상품 데이터를 추출할 수 있습니다. 이를 통해 전체 상품 데이터를 모두 추출하지 않고도 현재 페이지의 상품 데이터만 추출할 수 있으므로, 데이터베이스의 부하를 줄이고 Latency을 단축할 수 있습니다.
  • 여기서 인덱스는 id에 primarykey가 적용되어 자동으로 인덱스가 생성이 됩니다.
    - 저는 pagination을 이용하면 자동으로 type이 range인 쿼리를 실행할 것이라 생각했지만 그건 아니었습니다.[이 게시물에서 더 자세히 설명드리겠습니다.]
  • 페이지네이션 UI에서 사용자가 현재 어떤 페이지를 보고 있는지를 파악하기 쉬워집니다. 사용자가 명확하게 현재 페이지를 알면, 다음 페이지나 이전 페이지로 이동하기가 더 쉬워져서 사용자 경험을 개선할 수 있습니다.

결론

  • 따라서, 전체 상품 데이터 리스트에 pagination을 이용하면, 데이터베이스의 부하를 줄이고 응답 시간을 단축 할 수 있으며, 사용자의 UX가 향상됩니다.

일반적인 성능테스트

K6로 Smoke Testing, Load Testing, Stress Testing, Spike Testing순으로 해보았습니다.

Smoke Testing

스크립트를 실행하여 스크립트가 제대로 작동하는지, 시스템이 최소한의 로드에서 작동하는지 확인하고 기본 성능 값을 수집합니다.

다음 목표를 가지고 스모크 테스트를 실행하였습니다.

  • 테스트 스크립트에 오류가 없는지 확인
  • 최소한의 로드에서 시스템이 오류(성능 또는 시스템 관련)를 발생시키지 않는지 확인
  • 최소 부하에서 시스템 응답의 기본 성능 메트릭을 수집

Load Testing

Load Test는 시스템이 일반적인 날(일반적인 부하)에 성능 목표를 충족하는지 이해하는 데 도움이 됩니다. (여기서 일반적인 날은 평균적인 수의 사용자가 동시에 애플리케이션에 액세스하여 정상적이고 평균적인 작업을 수행하는 시간을 의미합니다.)

다음 목표를 가지고 로드 테스트를 실행하였습니다.

  • 일반적인 부하에서 시스템 성능을 평가
  • 램프 업 또는 완전 부하 기간 동안 초기 성능 저하 징후를 식별

일반적인 날 200명의 인원을 유지하도록 하고 http_req_duration이 0.5s 이하, 0.8s이하, 1.2s 이상 비율을 확인해보았습니다.

http_req_failed가 발생하지는 않았지만 0.5s 이하 비율은 2%, 0.8s 이하 비율은 3%, 1.2s 이상의 비율은 95%로 200명의 유저를 계속 유지할 때 Latency는 평균 16.4s가 나왔습니다. 최대 응답 시간은 27.02s로 너무 느려, 더이상 Stress Testing과 Spike Testing은 의미가 없다고 생각했습니다.

Cache가 필요한 이유

어떤 데이터를 캐싱해야할까?

  • 업데이트가 자주 발생하지 않는 데이터
    • 잦은 업데이트가 발생하는 데이터를 캐싱한다면 업데이트가 발생할 때마다 DB의 데이터와 캐시 데이터의 정합성을 맞추는 작업을 실시해야 하기 때문에 오히려 성능에 악영향을 줄 수 있습니다.
  • 자주 조회되는 데이터를 사용한다.
    • 조회 요청이 거의 없는 데이터를 캐싱한다면 그저 메모리만 낭비하는 데이터가 될 수 있으며, 조회시에도 본 스토리지에 요청을 보내기 전 캐시에 데이터가 존재하는지 확인해야하는 작업을 거치기 때문에 오히려 조회 속도가 더 느려질 수 있습니다.

전체 상품 데이터를 반환하는 리스트는 사용자에게 자주 조회되는 데이터이고 업데이트가 상대적으로 자주 발생하지 않다고 판단되어 cache를 적용하는 것이 좋다고 생각되었습니다.

따라서 Latency가 0.5s 이하, 0.8s 이하 비율을 더 높이고자 각 Page번호를 cache key로 적용시켰습니다.

Cache적용 후 Smoke Testing

Cache적용 후 Load Testing

Cache를 적용하니 http_req_duration(max)가 445.52ms로 개선할 수 있었고 Latency가 0.5s 이하의 비율이 100%로 200명의 유저를 유지 할 수 있었습니다.

Stress Testing

로드가 평소보다 무거울 때 시스템이 어떻게 작동하는지 평가합니다.

스트레스 테스트는 사용량이 많은 조건에서 시스템의 안정성과 신뢰성을 확인합니다. 시스템은 처리 기한, 월급날, 출퇴근 시간, 근무 종료 및 고부하 이벤트를 생성하기 위해 결합될 수 있는 기타 많은 격리된 동작과 같은 비정상적인 순간에 평소보다 높은 작업 부하를 받을 수 있습니다.

Load Testing 때보다 무겁게 시스템에 부하를 주기 위해 Vus를 400으로 늘리고 시간 역시 3배정도 길게 잡았습니다. http_req_failed 없이 http_req_duration이 0.5s 이하가 96%, 0.5s초과 0.8s이하가 2%, 1.2s 이상이 1%로 나왔습니다.

Spike Testing

시스템이 갑작스럽고 대량의 사용 급증에서 살아남고 성능을 발휘하는지 확인합니다. 이러한 이벤트의 예로는 티켓 판매(ComicCon, Taylor Swift), 제품 출시(PS5, 패션 의류), 판매 발표(슈퍼볼 광고), 처리 기한(세금 신고) 및 계절별 판매(블랙 프라이데이, 크리스마스, 세인트 발렌타인)가 있습니다.

다음 목표를 가지고 스파이크 테스트를 실행하였습니다.

  • 갑작스러운 트래픽 급증 시 시스템이 어떻게 작동하는지 확인
  • 갑작스러운 부하 급증에서 살아남을지 여부를 확인
  • 트래픽이 감소한 후 시스템이 복구되는지 여부를 판단

2분동안 2000명의 유저를 ramp-up하였고 1분동안 0명으로 ramp-down하게 해보았습니다.

http_req_dration에서 0.5s 이하로 나온 비율이 95%이고 1.2s 이상으로 나온 비율이 2였지만 http_req_faild가 0.89%가 나왔습니다.

http_req_failed가 0%로 나오는 Vus를 확인하기 위해 2000명 → 1500명 → 1200명 → 1000명 → 800명 → 750명 순으로 줄여보았습니다.

Vus가 750일 때 http_req_failed가 0%, http_req_duration이 0.5s 이하일 비율이 99%, 1.2이상인 횟수가 0%(15회번)을 확인 할 수 있었습니다.

따라서 flask로 구축한 서버에서 캐시와 pagination을 적용한 전체 상품 조회 API에서 갑작스러운 트래픽 부하 시 제대로 응답을 해줄 수 있는 Vus는 750이었습니다.

정리

  • 데이터베이스에 50만 데이터를 넣고 상품 조회 API를 테스트 해보니 pagination은 필수임을 몸소 느낄 수 있었습니다.
  • Cache를 사용하기 전에는 응답 Latency가 0.5s 이하 비율은 2%, 0.8s 이하 비율은 3%, 1.2s 이상의 비율은 95%였지만 Cache를 사용하여 데이터베이스의 부하를 줄이고 응답 Latency가 0.5s 이하의 비율이 100%인 상태로 200명의 유저를 유지 할 수 있었습니다.
  • Stress Testing으로 응답 Latency가 http_req_failed 없이 0.5s 이하가 96%, 0.5s 초과 0.8s 이하가 2%, 1.2s 이상이 1%로 400명의 유저를 유지 할 수 있었습니다.
  • flask 프레임워크를 사용해 서버 구축 후 전체 상품 조회 API에 Spike Testing 수행하면 http_req_failed 0%가 나오면서 최대 수용할 수 있는 Vus는 750임을 확인 할 수 있었습니다.
profile
방구석개발자

0개의 댓글

관련 채용 정보