Zero To One

성능테스트 정리할것 본문

서비스모니터링

성능테스트 정리할것

Zero_To_One 2022. 5. 12. 11:46

Achievement Goals

  • 시스템의 가용성과 확장성을 평가할 수 있다.
  • 부하 테스트의 목적을 이해할 수 있다.
  • Throughput과 Latency의 개념을 이해할 수 있다.
  • 시스템의 병목이 발생하는 주요 원인과 대책을 이해할 수 있다.
  • SLO를 설정하고, 이를 기반으로 부하 테스트를 진행하고, 달성 여부를 파악할 수 있다.

가용성과 확장성 평가

 

가용성과 확장성 Review

첫번째 유닛에서부터 가용성과 확장성을 염두하여 시스템을 설계하는 것의 중요성을 강조했습니다. 또한 다수의 노드를 가진 분산 시스템, 또한 서버리스 아키텍처 등을 통해 가용성과 확장성을 확보할 수 있다는 점 역시 배웠습니다.

다시 한번 정리를 하면 다음과 같습니다.

가용성

가용성(Availability)이란 시스템이 정상적으로 사용 가능한 정도를 말합니다. 정상적인 사용시간(Uptime)을 정상사용시간과 사용불가 시간을 합친 전체사용시간(Uptime + Downtime)으로 나눈값을 표현하며, 예를 들어 가용성 99.95%는 약 1년에 4시간 22분의 다운타임이 됩니다. 위의 수식에 따라서 서비스 사용 불가능 시간을 최소로 만들어야 가용성이 올라갑니다.

가용성의 핵심은 바로 단일 장애점(Single Point of Failure)을 없애는 것이어야 합니다. 즉, 어떤 한 노드가 장애가 발생해도, 동일한 처리 능력을 가진 다른 노드로 대체될 수 있어야 합니다. 이를 위해 필요한 것이 바로 시스템 확장입니다.

확장성

확장 가능한 시스템: 요구되는 시스템의 성능에 따라 동적으로 서버 구성이 변경되고, 시스템 처리 능력을 최적화할 수 있는 시스템을 의미합니다.

  • 시스템의 처리 능력을 확장하는 방법: 하나의 머신에서 메모리나 CPU를 늘리는 수직 확장(Scale Up), 머신의 인스턴스 수를 늘리는 수평 확장(Scale Out)
  • 수직 확장은 한계가 있으므로, 수평 확장이 가능할 때 확장성이 좋다고 평가할 수 있습니다.
  • AWS와 같은 클라우드 사업자가 확장성을 보증하는 경우도 존재합니다. 기본적으로 AWS 등에서 제공하는 서버리스 서비스들은 확장성이 좋습니다.

수직 확장을 고려할 경우 다운타임이 발생하여 가용성이 떨어지며, 성능 제한이 있으므로 반드시 한계를 이해해야 합니다.

 


부하 테스트의 목적

클라우드 환경에서의 부하 테스트 목적

클라우드 환경에서 부하 테스트를 하는 목적은 다음과 같습니다.

  1. 시스템 확장성을 가졌는지 확인
  2. 성능을 개선하기 위해 확장해야 하는 시스템이 무엇인지 파악
  3. 부하가 많이 발생할 때 문제 상황 개선
  4. 각 시스템의 병목 지점을 예측하고 진단 및 개선

1번은 앞서 "가용성과 확장성 평가"를 통해 확인하였으며, 나머지 각 항목에 대한 세부 사항도 함께 알아봅시다.

어떤 부분을 확장할 것인가?: 확장성에 대한 특징 파악

어떤 부분을 확장해야 성능이 높아질지를 고민하기에 앞서, Throughput과 관련한 지표를 먼저 이해할 필요가 있습니다. Throughput은 시간 당 처리량으로, 시스템의 성능 지표는 RPS(request per second), TPS(transaction per second)와 같은 단위로 표현됩니다. Throughput은 데이터 전송량에 포커스를 맞춘 성능 지표입니다. 한편 볼륨의 성능을 측정할 경우에는 IOPS(Input/Output per second)라는 단위를 사용합니다. 성능을 측정할 때는, 인프라 내의 구성요소(티어)로 구분된 각 요소를 구분하지 않고 통합해서, 특정 작업이 얼마만큼의 Throughput을 갖는지를 측정합니다.

그렇다면, 다음과 같은 질문을 던질 수 있을 것입니다.

  • 1000rps에서 2000rps로 성능을 두 배 개선하기 위해서는, 웹서버를 확장해야 할까? DB 서버를 확장해야 할까?
  • 시스템 구성 변경 시 다운타임은 얼마나 허용되는가? 서비스 정지 없이 가능한가?
  • 현재 시스템에서 낼 수 있는 최대 성능(limit)은 어디까지인가?

부하가 많이 발생할 때의 문제 상황 개선

사용자 요청이 많아지는 경우, 즉 부하가 많이 발생하면 실제로 시스템은 어떤 문제를 일으킬까요? 이 때 발생할 수 있는 요소는 다음과 같습니다.

  • 응답 속도(Latency) 저하
  • 시스템 잠금(Lock) 경합
  • 부하 발생시 애플리케이션 또는 서버 에러 발생
  • 데이터 일관성 문제와 손실

이러한 문제 상황을 해결할 수 있을 만큼의 부하의 수용 범위를 파악해야 합니다.

Action Items

Q. 시스템 잠금(Lock)에 대한 경합(Race condition)은 어느 때 발생하나요? 누가 무엇을 잠그는걸까요? (주로 DB에서 이러한 일이 발생합니다.)

병목 지점을 예측하고 진단 및 개선

"응답 성능의 병목 원인과 대책"에서 알아봅시다.

 

Throughput과 Latency

 

시스템 성능 지표의 주요 메트릭은 단연 Throughput과 Latency 입니다. 부하 테스트에서는 이 두가지 지표를 사용하여 평가합니다.

Throughput

시간 당 처리량을 의미합니다. 웹 애플리케이션 성능 지표로서의 throughput의 대표적인 예는 다음과 같습니다.

  • 1초에 처리하는 HTTP 요청 수 (rps)
  • (동영상 스트리밍 서비스와 같이 대역폭이 중요한 경우) 네트워크로 전송되는 데이터 전송 속도

Latency

처리 시간을 의미합니다.

사용자가 어떤 웹페이지를 보기 위한 Latency는 사용자의 인터넷 환경, 브라우저 등의 개별 환경에 대한 변수가 존재합니다. 즉, "네트워크를 통한 데이터 왕복 시간"도 포함합니다. 그러나 성능 테스트를 진행할 때에는, 사용자 환경에 따른 변인을 통제하거나, 애초에 네트워크 상황을 고려하지 않고 테스트를 진행합니다. 이후 언급하는 Latency는 네트워크 상황을 고려하지 않은 시스템이 요청을 받고 응답을 줄 때까지의 시간만을 의미할 것입니다.

하위 시스템으로 구성된 경우에서의 Throughput과 Latency

다음 고속도로의 비유를 통해 Throughput과 Latency를 이해할 수 있습니다. 여기서 하위 시스템은 서울/대구/부산 각각의 도시를 의미하며, 각 도시 간에는 서로 다른 Throughput과 Latency를 가진 고속도로 두 개가 존재한다고 가정합시다.

  • 이 때 Latency는 대기 시간을 포함한, 각 하위 시스템 처리 시간의 총 합으로 계산합니다.
  • 반면 Throughput은 하위 시스템 Throughput 중 최솟값을 전체 시스템의 Throughput으로 계산합니다.
  • 서울-부산 간 Latency: 각 구간의 소요 시간 합계인 5시간
  • 서울-부산 간 Throughput: 각 구간에 도달하는 차량 대수 중 최소값인 800대/시간

 

병목 구간의 확인과 개선 기본 지식

 

시스템 성능 지표인 Throughut과 Latency를 바탕으로 개선할 경우, 어떤 부분을 먼저 개선해야 하는지 사례를 통해 알아봅니다.

Throughput 개선

고속도로의 예를 다시 빌려, 다음과 같이 세 도시를 연결하는 두 개의 고속도로 중 대구-부산간 고속도로가 병목을 일으키고 있다고 가정합시다.

이 때, 서울-부산 사이의 Throughput은 최솟값인, 200대/시간에 불과합니다. 이런 경우에는 도로 확장 공사를 통해 병목을 해결합니다. 확장 공사를 마친 대구-부산간 고속도로의 Throughput이 800대/시간으로 개선되었습니다.

병목이 아닌 구간(서울-대구)을 개선하는 것은, 전체의 Throughput을 개선하는 데에 전혀 도움이 되지 않습니다. 도리어 대구-부산간의 정체가 늘어나 Throughput이 감소할 수도 있습니다. 따라서, Throughput 개선을 위해서는 병목 구간이 어디인가를 먼저 파악하는 것이 가장 중요합니다.

Latency 개선

애플리케이션 개선

Latency의 개선은 개발된 애플리케이션을 개선하는 것으로 시작합니다. 애플리케이션 성능 최적화는 현상을 파악(APM, Application Performance Monitoring)하는 것으로 시작하며, 알고리즘 개선, I/O 최소화 등의 개선 방안이 뒤따릅니다. DevOps가 이를 모니터링할 수는 있으나, 결국 개발자가 APM 도구와 프로파일러 등을 이용해 이를 개선해야 합니다.

(애플리케이션 성능 향상을 위한) 하위 시스템의 확장

한편 앞서 고속도로의 예를 살펴보면, Throughput의 개선이 Latency의 개선으로 이어진 것을 확인할 수 있습니다. 이는 곧 "대기 시간"에 문제가 있다는 의미입니다. 만일 애플리케이션이 실행 환경(하위 시스템)의 성능을 최대한 활용할 수 있다면, 하위 시스템의 확장에 따라 Throughput도 개선되며, 대기 시간도 줄어듭니다. 즉 많은 경우 Throughput이 개선되면 Latency도 개선됩니다.

 

응답 성능의 병목 원인과 대책

 

응답 성능의 병목 원인과 대책

서비스를 시작한 후 발생할 수 있는 문제 시나리오는 다양합니다. 이러한 문제는 응답 성능의 병목을 가져다줍니다. 아래 제시된 시나리오는 매우 일반적이며, 부하 테스트를 통해 응답 성능을 예측할 수 있습니다. 애플리케이션 수준에서의 대책을 온전히 이해하기는 어렵지만, 주요 키워드를 학습하여 개발자에게 솔루션을 제공할 수는 있어야 합니다.

  1. 많은 사용자의 서비스 등록
  2. 많은 데이터의 저장
    • 1,2번과 같은 경우 DB에 데이터가 증가합니다. secondary 복제본 등을 이용해 읽기/쓰기를 분리하거나, 검색에 최적화된 인덱스 사용을 고려할 수 있습니다.
  3. 단기간 동안의 사용자 요청 증가(peak traffic)
    • Auto Scaling이 해결책이 될 수 있습니다. 다만 버스트 성능에 대해 이해해야 합니다.
  4. 배치 작업을 진행하는 데이터베이스
    • DB가 주기적으로 스냅샷을 만들거나, 데이터 일관성을 위해 레플리카와의 sync 과정을 진행하는 등의 배치 작업이 이루어질 경우, primary DB는 성능 저하가 발생할 수 있습니다. 이 때 사용자들의 요청과 맞물려 서비스 수준을 맞추기 어려울 수 있습니다.
  5. 많은 양의 로그 수집 처리
    • 애플리케이션이 잘 작동할 때에는 로그를 많이 남기지 않지만, 애플리케이션에 문제가 발생하면 추적을 위해 많은 로그를 남깁니다. 다만 이러한 상황이 반복적으로 진행될 경우, 에러 로그 수집 그 자체가 애플리케이션 병목을 일으킬 수 있습니다.
  6. 시스템 재시작 후의 캐시 초기화
    • 큰 문제를 발생시키는 것은 아니지만, 캐시가 초기화되면서 시스템으로 직접적인 요청 횟수가 증가할 수 있습니다.

Action Items

  • Q. AWS에서는 버스트 가능한 인스턴스의 경우, CPU 성능을 적게 사용하는 평상시에는 "크레딧"을 누적했다가, 단기간의 사용자 요청 증가와 같이 CPU 사용량이 증가할 경우, 모아둔 크레딧을 성능을 끌어올리는 용도로 사용할 수 있습니다. 이 때 잔고에 충분한 크레딧이 있어야 합니다. 그렇지 않을 경우 100%의 CPU 성능을 제공하지 못하여, 파열(burst)에 이르며, 시스템 사용 불능 상태가 됩니다. 어떠한 메커니즘으로 작동하는지 한번 알아보세요.

주요 병목 구간과 부하 테스트 시 고려해야 할 부분

병목 구간을 확인하는 것은 부하 테스트의 주요 목적이면서, 또한 좋은 부하 테스트를 만드는 기본입니다. 시스템에서 문제가 발생할 수 있는 부분을 다이어그램으로 표현하면 다음과 같습니다.


부하 테스트 계획

부하 테스트를 진행하기 앞서, 서비스 수준 목표(SLO)를 설정하는 것이 좋습니다. 먼저 척도를 표준화 하고, 다음과 같은 목표를 설정합니다.

Latency에 중점을 둔 SLO 예시

  • GET 호출의 90%는 1ms 이내에 완료해야 합니다.
  • GET 호출의 99%는 10ms 이내에 완료해야 합니다.
  • GET 호출의 99.9%는 100ms 이내에 완료해야 합니다.

Throughput에 중점을 둔 SLO 예시

결국 Throughput은 순간적으로 요청이 치솟는 피크(peak) 트래픽에서의 처리량을 바탕으로 합니다.

예를 들어, 1일 기준으로 RPS를 계산하고자 할 때, 다음과 같은 시나리오를 생각해볼 수 있습니다.

  • DAU(Daily Active User: 1일 접속자 수): 5만명
  • 1명당 평균 접속 횟수: 20회
  • 1일 평균 접속 수에 대한 피크 트래픽 배율: 3배 (보통 평균의 2~3배를 곱합니다)
  • 안전 계수 (얼마만큼 넉넉하게 프로비저닝 할 것인가): 3배

이 경우 하루가 총 86400초이므로, 다음과 같이 RPS를 생각해볼 수 있습니다.

50000 x 20 / 86400 x 3 x 3 = 104RPS (약 100RPS)

이를 바탕으로 도출한 SLO는 다음과 같습니다.

  • 서비스는 초당 100PRS를 달성해야 합니다
 

부하 테스트 도구

다양한 부하 테스트 도구가 존재합니다. 부하 테스트 툴은 회사/조직별로 사용하는 프로그램의 범위가 넓고 다양하므로, 여기서는 특정 테스트 도구의 사용방법을 다루기보다는, 도구 중 하나를 택하여 문서를 통해 배우고, 직접 계획을 세우고 실행해보는 데에 의의를 둡니다. 다음 레퍼런스를 참고하세요.

최근 주목받고 있는 부하 테스트 도구를 소개합니다. 기본적으로 무료로 사용할 수 있는 CLI 도구를 제공하지만, 추가 기능을 SaaS 형태로도 제공합니다.