본문 바로가기
🌿 Data Engineering/MLOps

[로컬에서] Locust사용법, API 부하 테스트 및 성능 지표 해석하기

by 카프리썬_ 2024. 8. 6.
728x90
728x90

데이터엔지니어링 업무를 하다보면, 모델의 추론서버나 모델을 서빙하기 위한 API를 개발해야하는 상황이 생긴다.

일단 개발했을때는 나혼자 사용하기 때문에 문제가 없을수도 있다.

그러나 이 서버를 실제 서비스에 배포했을 때, 많은 request가 들어오기 때문에 예상하지 못한 문제가 생길지도 모른다. 

 

이렇게 구축된 서버의 성능을 사전에 확인하고자 스트레스 테스팅(부하 테스트)을 할수 있다. 

이전에는 nGrinder를 별도의 서버(Ec2)에 설치해서 사용했는데 약간의 러닝 커브가 있었다.

그래서 조금더 간단한 locust로 성능테스트 하는 방법을 알아보려고 한다. 

 

https://locust.io/

 

Locust.io

An open source load testing tool. Define user behaviour with Python code, and swarm your system with millions of simultaneous users.

locust.io

 

 

locust 사용법은 굉장히 간단하다. locust를 설치하고, 테스팅할 스트립트를 파이썬으로 작성한뒤, 실행하기만 하면 된다. 

파이썬기반이라 설치와 스트립트 작성이 간단하고, 웹에서 성능 결과를 그래프와 표로 아주 직관적으로 보여준다. 

 

설치 

pip install locust

2.29.1 버전을 설치했다.

 


스크팁트 작성 

locustfile.py를 작성한다.

 

사실 아래 코드는 파리미터를 키워드로 받는 API를 테스트하는 스트립트이다.

파라미터인 keyword는 실제로 운영환경에서 request로 들어왔던 keywords를 뽑아 랜덤하게 요청했다. 

import json
import random

from locust import HttpUser, task

keywords = []
with open("keywords.txt", "r") as f:
    keywords = [keyword.strip() for keyword in f.readlines()]


class PerformanceTester(HttpUser):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self._uri = "/api/your/endpoint/"
        print(f"self._uri={self._uri}")
        print(f"keywords size = {len(keywords)}")

    @task
    def run_test(self):
        keyword = random.choice(keywords)
        size = 14
        params = {"keyword": keyword, "size": size}
        self.client.get(url=self._uri, params=params)

 

 

실행 

 locust -f locustfile.py

사실 파일명은 꼭 locustfile.py 가 아니여도 된다.

 

 

테스트

실행후 로컬에서 8089 포트로 접속한다.

 

테스트를 시작하기 전에 몇가지 조정할게 필요하다. 

  • Number of User : 최대 유저수 
    보통 4, 8, 16, 32 이렇게 설정하는데 점차적으로 유저수가 증가하며 테스트가 진행된다.
  • Ramp up  (시작유저/sec) : 한번에 유저가 생성되는 수
    한번에 폭발적으로 많은 유저가 인입되는 케이스를 테스팅하고 싶다면 요걸 올리면 될것 같다. 
  • Host : 부하테스트할 서버 주소 
    정확한 테스트를 위해 부하테스트할 서버(로컬)과 다른 host주소를 테스트하길 권장한다. 
  • Advanced options (Run time): 부하테스트를 진행할 시간

 

테스트 결과

이렇게 실시간으로 그래프에 찍히는걸 볼수 있다. 보니까 이 테스트는 초반에 response time이 튀는 부분이 존재한다. 

보안상 호스트이름은 가렸다.

 

그리고 결과 차트로도 이렇게 확인할수 있다.

총 요청수와, 중간값 과 평균값 p95와 p99le 값, 최소와 최대속도 그리고 RPS까지 표로 한눈에 볼수 있다. 

 

성능 지표 해석

p99와 p95는 극단적인 케이스를 제외한 대다수의  응답시간을 확인할 수 있는 지표이다.

이 값이 높은 케이스에는(종종 튀는 부분) 일부 사용자에게 성능 병목 지점이 생겼다는 의미로 해석할수 있다.

 

p99의 상위 1%의 응답시간으로, 100명의 사용자가 있다면 99번째로 느린사용자(상위1%)가 경험한 응답시간이다. 

예를 들어 100개의 요청중 99번째 응답시간이 2초라면, p99는 2초가 되는 것이다.

결국 99%의 사용자가 2초 이내에 응답했고, 나머지 1% 사용자만 2초보다 더 오래 걸렸다는 뜻이다.

p95도 마찬가지다. 95퍼센타일로 520ms라면, 95%가 520ms이내로 응답했다는 뜻이다. 

 

그리고 중간값과 평균값 그리고 최대속도와 최소속도는 의미대로 해석할 수 있다. 

 

RPS는 Request Per Second의 약자로, 초당 요청수를 의미한다. 

이 값이 높을수록 1초당 처리할 수 있는 요청수가 많다는걸 의미로 해석할 수 있다. 

 

실제로 우리 서비스의 모니터링 툴인 datadog에서도 위의 지표들을 확인할수 있다.

 

 

마무리하자면 개발한 API서버를 배포하기전에 이렇게 로컬에서 locust를 사용해서 부하테스트를 해볼수 있다.

그리고 p99,p95, RPS 등 각각의 성능지표와 그래프를 보고, API의 성능이 어떤지까지 확인해볼수 있을 것이다. 

 

여담이지만 Locust의 뜻은 메뚜기이다!

 

 

728x90
반응형