재형이의 성장통 일지
  • 서버리스 기반 부하테스트 진행 방법
    2024년 04월 18일 04시 55분 32초에 업로드 된 글입니다.
    작성자: 재형이
    반응형

    Serverless 기반에서 부하테스트 진행 방법

    • 부하테스트란 실제 운영 환경에서 사용자의 요청량이나 데이터 처리량을 예상하여 시스템의 성능 한계를 측정하는 것을 말합니다. 부하 테스트를 통해 애플리케이션의 탄력성, 안정성 및 확장성을 검증할 수 있습니다.
    • 시스템이 사용자의 요구 사항을 충족시킬 수 있도록 하여 사용자의 만족도를 높일 수 있습니다.

    부하테스트 진행 절차

    1. 테스트 툴 선정
    2. 테스트 시나리오 정의
    3. 목표 지표 정리 ( 응답 속도, 유저 수 )
    4. 인프라 파악
    5. 테스트 준비
    6. 테스트 진행 & 결과 기록
    7. 개선 방향 정리 & 결과 적용

    1단계: 테스트 툴 선정

    • 테스트 툴 선정 시 고려할 점
      1. 프로그래밍 언어를 너무 신경 쓰지 말자
      2. 요구되는 트래픽이 높으면 Cloud 환경에서 쉽게 확장 가능한지 확인
      3. 단순히 멋져보이는 힙스터 도구의 사용을 지양
      4. 사용자 많고 스타 수 높은 툴로 가는 것을 추천

    여러가지 테스트 툴

    • Locust
      • Python으로 작성되어 있으며, 사용이 간편하고, 넓은 사용자 풀
      • Amazon ECS Fargate Spot을 이용한 저렴한 분산 부하 테스트가 가능
      • Web UI를 통해 트래픽 변화를 쉽게 모니터링 
      • AWS Solutions Architect 직원분도 추천할 정도로 사용자 풀이 넓고 생태계 발전이 잘 되어 있음
      • 조대협 강사님도 언급하셨었던 툴
      • 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

    • k6
      • JavaScript로 시나리오를 작성
      • Grafana에서 제공하는 k6 Cloud를 통해 비용을 지불하고 테스트할 수 있음
      • Grafana k6 Cloud 한정으로 대량 부하 발생 시 Grafana k6 Cloud에서 단일머신을 활용하기 때문에 부하발생기의 성능이 따라오지 못하는 이슈가 간혹 발생함
      • https://k6.io/
     

    Load testing for engineering teams | Grafana k6

    k6 is an open-source tool and cloud service that makes load testing easy for developers and QA engineers.

    k6.io

    • Artillery
      • Yaml과 JavaScript로 시나리오를 작성
      • AWS Lambda와 Fargate를 활용한 분산 부하 테스트에 적합
      • 잦은 오류 발생 (24.01.31 기준)
      • https://www.artillery.io/
     

    Artillery.io | Cloud-scale Load Testing

    Keep production reliable, customers happy, and pagers silent.

    www.artillery.io

    • 기타 유명한 도구로는 Apache JMeter, nGrinder, Gatling 등이 있습니다.

    2단계: 테스트 시나리오 정의

    • 애플리케이션의 모든 API를 정리하는 것이 매우 중요합니다. 이 과정에서 실제 운영 환경에서 발생할 수 있는 다양한 상황을 시나리오로 구성하는 것입니다. 
    • 테스트 시나리오 작성 시 애플리케이션의 모든 기능과 API 호출을 포괄해야 합니다. 하나도 빠짐 없이!
    • 시나리오가 어떤 역할을 하는지, 애플리케이션의 어떤 기능과 관련이 있는지 최소 90% 이상은 이해하고 있어야 합니다. 특히 시나리오를 코드로 작성할 때는 각 태스크의 가중치 값을 프레임워크가 지원하는 방식으로 적절하게 조정합니다. (예: view_item 태스크 가중치는 3)
    • Locust 시나리오 예시
      https://github.com/locustio/locust/blob/master/examples/locustfile.py
     

    locust/examples/locustfile.py at master · locustio/locust

    Write scalable load tests in plain Python 🚗💨. Contribute to locustio/locust development by creating an account on GitHub.

    github.com

    from locust import HttpUser, between, task
    import time
    
    class QuickstartUser(HttpUser):
        wait_time = between(1, 2)
    
        @task
        def hello_world(self):
            self.client.get("/hello")
            self.client.get("/world")
        
        @task(3)
        def view_item(self):
            for item_id in range(10):
                self.client.get(f"/item?id={item_id}", name="/item")
                time.sleep(1)
    
        def on_start(self):
            self.client.post("/login", json={"username": "foo", "password": "bar"})

    3단계: 목표 지표 정리 ( 응답 속도, 유저 수 )

    • 응답 속도와 목표로 하는 동시 사용자 수(가상 사용자, VU)와 같은 중요한 지표들에 대한 목표 값을 설정
    • 응답 속도는 퍼센타일 지표(p50, p95, p99)를 사용, 예를 들어, 95%의 요청이 몇 밀리초(ms) 이내에 응답을 받아야 하는지를 결정 → 예시) 초당 VU 10만명이 10초동안 들어왔을 때 latency p95 200ms
    • 현재 서비스가 원활하게 운영되고 있을 때 응답 속도를 측정하고 이를 기반으로 성능 지표를 잡거나, 과거 데이터를 기반으로 특정 사용자 수(VU)에 대한 응답 속도와 성능을 이해하고 목표 지표를 정립할 수 있습니다

    4단계: 인프라 파악

    • 모든 리소스를 면밀히 검토하고 문서화하는 것이 중요합니다
    • API 서버의 경우 각 API 별로 사용하는 리소스와 의존성을 정확히 파악하는 것이 필수
    • 테스트 중 발견될 수 있는 성능 문제 또는 병목 현상을 인프라와 연결지어 트러블슈팅하는데 도움이 되는 과정입니다.

    5단계: 테스트 준비

    • 부하 테스트를 위해 실제 운영 환경과 가능한 한 똑같이 복제
    • 데이터베이스를 똑같이 복제함으로써 실제 운영 시 발생할 수 있는 쿼리 성능을 진단 가능
    • 실제 운영 환경과 유사한 유저 데이터를 테스트 환경에 추가

    6단계: 테스트 진행 & 결과 기록

    • 정의된 시나리오에 따라 실제 부하 테스트를 진행하고, 그 결과를 체계적으로 기록
    • 테스트 중에는 모든 변수를 통제하고, 예상치 못한 병목 현상을 발견하기 위해 다양한 리소스를 모니터링
    • 변경이 가능한 리소스 환경일 경우 신속하게 리소스 변경이 이루어질 수 있도록 사전에 환경을 구축
    • 리소스의 모든 하드웨어를 병목 대상 후보로 두기 (CPU, Memory, Network, Storage 등)
    • 네트워크 성능 이슈가 자주 발생하므로 네트워크 성능에 대한 기대치를 낮춰야 함
    • 지표에 너무 매몰되어 시간을 허비하지 말자 (시나리오와 100% 일치하게 테스트하는 것은 어려움)

    7단계: 개선 방향 정리 & 결과 적용

    • 개선 방향은 아키텍처 변경, 서비스 로직 변경 등이 주로 있습니다. 
    • 해당 결과를 모두 운영 환경에 한번에 적용하기보단 점진적으로 배포해가며 모니터링을 통해 적용하여 나가는 것이 중요합니다
    • 부하 테스트는 지속적인 성능 모니터링과 함께 주기적으로 반복해야 하는 과정입니다. 이를 통해 시스템의 성능을 지속적으로 개선하고, 변경되는 사용자 요구와 트래픽 패턴에 효과적으로 대응할 수 있습니다.

    부하 테스트 시 유용한 팁

    • 공통
      • 변수 단일화:
        테스트 1회 당 하나의 변수만 변경하며 테스트하는 것이 권장됩니다. 이렇게 하면 어떤 변경이 성능에 영향을 미치는지 명확하게 알 수 있습니다.
      • 비용 투자
        단기적으로 비용이 들어가더라도 빠르게 테스트를 진행하여 문제를 해결하는 것이 장기적으로 시간과 비용을 절약하는 방법입니다.
      • 확장 전략
        성능 문제에 대응하기 위해 스케일 업(수직 확장)과 스케일 아웃(수평 확장) 중 적합한 전략을 선택합니다.
    • AWS Support 및 Solutions Architect 팀
      • Support 케이스를 제출할 때 상황에 대해 구체적으로 설명해주시면 빠르고 자세한 분석이 가능
      • 예를 들어, 부하 테스트 방식, 시나리오, 목적 등에 대해 기재해주시면 Support Engineer들이 고객분들의 입장에서 분석하기 수월
      • 추가로, 각 제품별로 케이스를 올려주시면 보다 전문적인 답변을 제공 받으실 수 있습니다.
    • AWS ECS Fargate
    • AWS RDS Aurora (Postgres)
      • 주요 변수: CPU, Memory, DB Connection count, Network
      • Serverless 주요 변수: Serverless Capacity
      • Enhanced Monitoring 활성화를 통해 OS 지표에 대한 자세한 확인이 가능하며 Performance Insights를 활용해 성능 최적화를 검토 가능
      • 모니터링은 Performance Insight와 Monitoring 탭에서 주로 진행
      • Performance Insights를 활성화하면 DB Load와 대기 이벤트에 대한 확인이 가능합니다. 많이 발생하는 대기 이벤트와 연관 된 쿼리를 확인하여 쿼리를 최적화하거나 워크로드의 개선 및 스케일 업/아웃에 대한 검토 자료로 활용할 수 있습니다. 예를 들어, Performance Insights에 LWLock:lock_manager이 관측될 경우 connection pool이 문제가 되는 경우가 있으므로 RDS Proxy 적용 고려
      • Performance Insights CPU 대기가 길다면 문제가 되는 쿼리의 최적화 지점을 살펴보거나 Scale up/out 진행
      • 대량의 테스트 데이터가 들어갔다면 vacuum analyze 쿼리 실행
      • 쿼리 실행 계획: 사용자는 EXPLAIN 명령을 통해 쿼리의 실행 계획을 확인할 수 있습니다. 특정 쿼리로 인해 리소스가 많이 사용되거나 성능이 저하된다면 쿼리의 실행 계획을 출력하여 성능에 영향을 미치는 사항을 확인할 수 있습니다.
      • PostgreSQL에서는 정해진 threshold를 만족하면 autovacuum이 자동으로 수행되지만 pg_stat_all_tables 혹은 pg_stat_user_tables 뷰를 통해 가장 최근 수행 된 vacuum 작업에 대한 이력을 확인하고 수동으로 vacuum 수행을 고려해볼 수 있습니다.
    • AWS ElastiCache for Redis
      • 주요 변수: Memory, CPU, Network
      • 파이크 테스트 중 예상치 못한 네트워크 지연이 크게 발생할 수 있습니다. 이 경우, 문제의 원인을 정확히 파악하기 위해 네트워크 성능을 철저히 모니터링해야 합니다
      • Redis는 싱글 스레드이며, 한 번에 하나의 vCPU만 사용됩니다. 때문에 대량의 쿼리가 발생하거나 Slow 쿼리가 처리될 때 응답 속도가 저하될 수 있습니다. 이런 경우, 여러 노드로 분산하여 처리
      • 키 관리 최적화: Redis에서는 작고 표준화된(동일한 크기와 타입을 가진) 키를 사용하는 것이 성능에 유리합니다. 크기가 큰 키는 성능에 불리할 수 있습니다. redis-cli --bigkeys 명령어를 사용하여 샘플 키들을 검사하고, 너무 큰 키로 인해 발생하는 성능 저하가 없는지 확인하는 것이 좋습니다

     
     
     
     
     
     


     
     
     
     

    Reference

     

    AWS KRUG - Serverless 소모임 - 20240416

    안녕하세요 늑대양입니다 전일(240416) 진행되었던 AWS KRUG Serverless 소모임에서 진행된 세션 내용 하나를 공유드릴까합니다 아래부터는 세션을 들으면서 작성한 내용입니다. Serverless 기반의 부하

    wolf-sheep.tistory.com

     

    Wonderwall 은 부하 테스트를 어떻게 진행했을까? | Amazon Web Services

    엔터테크 기업 (주)노머스는 종합 아티스트 IP 서비스 ‘원더월’을 선두로, “예술이 세상을 바꾼다(Art Changes Life)”라는 슬로건을 바탕으로 아티스트 IP 기반의 콘텐츠, 커머스, 공연, 팬덤 플랫

    aws.amazon.com

     

    스타트업의 부하 테스트 AtoZ : Wonderwall Tech

    스타트업의 부하 테스트 AtoZ by seonhyung

    tech.wonderwall.kr

     

    Grafana k6 사용하여 부하테스트 하는 방법 1

    부하테스트를 진행하기전에 어떠한 테스트들이 있고, 테스트를 위한 설정 값들은 무엇이 있는지 알아보자. Smoke Test 최소 부하 상태에서 시스템에 오류가 발생하는지 확인하는 테스트 VUser: 1~2로

    developer-pi.tistory.com

     

    반응형

    '데브옵스' 카테고리의 다른 글

    DEVOPS/SRE 란?  (2) 2024.04.07
    댓글