프로필사진
DevOps 부트캠프 기록일지
DevOps_04_김재환
2023.06.07(가용성과 확장성 평가)
2023.06.07(가용성과 확장성 평가)

2023. 6. 7. 15:39부트캠프/DevOps (TIL)

애플리케이션 또는 시스템의 성능을 평가하는 것은 중요한 작업입니다. 성능테스트는 가용성과 확장성을 평가하는 데 도움을 줄 수 있습니다. 이 블로그 포스트에서는 가용성과 확장성 평가에 대해 알아보고, 이를 위한 몇 가지 중요한 지표와 방법을 살펴보겠습니다.

 

가용성(Availability)이란?

- 시스템이 정상적으로 사용 가능한 정도
uptime / (uptime + downtime)
  => 정상가동시간(uptime), 사용 불가 시간(downtime), 합친 전체 사용 시간 (uptime + downtime)
- ex) 가용성 99.95% = 약 1년에 4시간 22분의 다운타임을 갖습니다.

* 단일 장애점 (Single Point of Failure)을 없애야 합니다.
** 어떤 한 노드에서 장애가 발생해도, 동일한 처리 능력을 가진 다른 노드로 대체 될 수 있어야 합니다.
     => 시스템 확장이 필요합니다.

 

[가용성 평가]

가용성은 시스템이 요청에 신속하게 응답하고 지속적으로 작동할 수 있는 능력을 의미합니다. 성능테스트에서 가용성을 평가하기 위해 다음과 같은 지표와 방법을 사용할 수 있습니다:

  1. 응답 시간: 시스템이 요청을 처리하는 데 걸리는 시간을 측정합니다. 이는 사용자가 얼마나 빠르게 응답을 받을 수 있는지를 판단하는 데 도움을 줍니다.
  2. 처리량: 시스템이 단위 시간당 처리할 수 있는 요청의 양을 측정합니다. 이를 통해 시스템이 얼마나 많은 요청을 동시에 처리할 수 있는지를 확인할 수 있습니다.
  3. 오류율: 시스템이 요청을 처리하는 과정에서 발생하는 오류의 비율을 측정합니다. 오류율이 높다면 시스템의 가용성이 저하되고 있을 수 있으므로 주의해야 합니다.

가용성 평가를 위해 성능테스트 도구를 사용하거나 부하 테스트를 수행할 수 있습니다. 부하 테스트는 시스템에 예상되는 작업량 이상의 부하를 가하여 시스템의 반응을 확인하는 과정입니다.

 

확장성(Scalability)이란?

- 요구되는 시스템의 성능에 따라 동적으로 서버 구성이 변경되고
   시스템 처리 능력을 최적화 할 수 있는 시스템입니다.

시스템 처리 능력 확장 하는 법
- 하나의 머신에서 메모리나 CPU를 늘리는 수직확장(Scale Up), 머신의 인스턴스 수를 늘리는 수평확장 (Scale Out)이 있습니다.
- 수직 확장은 한계가 있으므로 수평 확장이 가능할 때 확장성이 좋다고 평가할 수 있습니다.
- AWS와 같은 클라우드 사업자가 확장성을 보증하는 경우도 있습니다.
- 서버리스 서비스들은 확장성이 좋습니다.
* 수직확장을 고려할 경우 다운타임이 발생하여 가용성이 떨어지고 성능 제한이 있으므로 반드시 한계를 이해해야 합니다.

 

[확장성 평가]

확장성은 시스템이 추가적인 부하 또는 사용자 요청에 대해 효율적으로 대응할 수 있는 능력을 의미합니다. 성능테스트에서 확장성을 평가하기 위해 다음과 같은 지표와 방법을 사용할 수 있습니다:

  1. 수평 확장성: 시스템의 인스턴스 수를 늘려서 처리할 수 있는 부하의 증가 여부를 확인합니다. 즉, 시스템이 더 많은 서버나 노드를 추가하여 성능을 향상시킬 수 있는지를 알아봅니다.
  2. 세로 확장성: 시스템 내부의 구성 요소(예: 데이터베이스 서버, 웹 서버)를 추가하여 처리할 수 있는 부하의 증가 여부를 확인합니다. 이는 시스템이 새로운 인스턴스를 추가하여 성능을 확장할 수 있는지를 평가하는 데 도움을 줍니다.
  3. 응답 시간 유지: 부하가 증가할 때에도 시스템이 일정한 응답 시간을 유지할 수 있는지 확인합니다. 이는 사용자 경험과 시스템의 가용성에 중요한 영향을 미치는 지표입니다.
  4. 자원 사용률: 시스템의 자원(예: CPU, 메모리, 대역폭) 사용률을 측정하여 시스템이 추가 부하에 대해 충분한 여유 자원을 가지고 있는지를 확인합니다. 자원 사용률이 과도하게 증가한다면 시스템의 확장성에 문제가 있을 수 있습니다.

확장성 평가를 위해 성능테스트에서는 부하 테스트를 수행하고, 다양한 환경에서 시스템의 성능을 측정합니다. 이를 통해 부하가 증가함에 따라 시스템이 어떻게 반응하는지를 확인하고, 병목 현상이나 성능 저하가 발생하는 부분을 찾아낼 수 있습니다.

 

부하테스트의 목적

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

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

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

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

 

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

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

 

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

 

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

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

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

 

Action Items

  • 1000rps에서 2000rps로 성능을 두 배 개선하기 위해서는, 웹서버를 확장해야 할까? DB 서버를 확장해야 할까?

일반적으로 웹서버와 DB 서버는 웹 응용 프로그램의 성능을 영향을 주는 주요 구성 요소입니다. 그러나 이 두 서버 중에서 어느 것을 확장해야 하는지 결정하기 위해서는 다음과 같은 요소를 고려해야 합니다.

  1. 병목 현상(Bottlenecks): 현재 시스템에서 성능에 가장 큰 영향을 주는 병목 현상이 무엇인지 확인해야 합니다. 웹서버와 DB 서버 간의 상호작용을 분석하여 어느 서버가 성능 저하의 주요 원인인지 확인할 수 있습니다.
  2. 요청 및 응답의 복잡성: 웹 응용 프로그램의 요청 및 응답 복잡성을 고려해야 합니다. 데이터베이스 작업이 많고 복잡한 경우에는 DB 서버를 확장하는 것이 유리할 수 있습니다. 반면, 정적 콘텐츠의 처리가 주로 웹서버에서 이루어진다면 웹서버의 확장이 필요할 수 있습니다.
  3. 시스템 리소스 사용량: 현재 시스템에서 각 서버의 리소스 사용량을 확인해야 합니다. CPU, 메모리, 디스크 I/O 등의 사용량을 모니터링하여 어느 서버가 더 많은 리소스를 사용하고 있는지 확인할 수 있습니다. 리소스 사용량이 높은 서버를 확장하는 것이 성능 개선에 도움이 될 수 있습니다.
  • 시스템 구성 변경 시 다운타임은 얼마나 허용되는가? 서비스 정지 없이 가능한가?

다운타임을 허용할 수 있는 시간은 시스템의 중요도, 사용자 기대 수준, 시스템 규모, 특성 등에 따라 다릅니다.

 

다운타임에 대한 영향이 큰 경우 (금융이나 의료 서비스 등) 다운타임 허용 시간이 매우 짧을 것이고, 커머스 웹사이트 블로그 등 심각한 결과가 발생하지 않는 경우는 다운타임 허용 시간이 좀 더 허용 될 것입니다.

서비스 정지 없이 시스템 구성을 변경하기 위해선 고 가용성 아키텍처와 같은 시스템 구축이 필요합니다.

로드 밸런스 등의 기술을 사용하여 여러대의 서버 구성이 필요합니다.

  • 현재 시스템에서 낼 수 있는 최대 성능(limit)은 어디까지인가?

하드웨어 성능 (CPU, 메모리 등), 소프트웨어 성능 (어플리케이션 코드 최적화, 데이터베이스 쿼리 최적화 등), 네트워크 대역폭이나 지연시간 등 네트워크 성능도 시스템 성능에 영향을 미치며 또한 시스템 구조 및 아키텍처에 따라 성능이 제한 될 수 있습니다.

이러한 것들을 고려하여 최적의 구성을 하여 최대 성능을 달성할 수 있습니다.

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

시스템 잠금 경합(Race condition)은 동시에 여러 스레드나 프로세스가 공유 자원에 접근하려고 할 때 발생할 수 있습니다. 이러한 경합은 일반적으로 다음과 같은 경우에 발생할 수 있습니다:

  1. 병렬 처리: 병렬로 동작하는 여러 스레드나 프로세스가 공유 데이터나 자원에 동시에 접근하는 경우 발생할 수 있습니다. 예를 들어, 동시에 여러 스레드가 동일한 데이터베이스 레코드를 수정하려고 할 때, 잠금 경합이 발생할 수 있습니다.
  2. 트랜잭션 격리 수준: 데이터베이스의 트랜잭션 격리 수준이 낮은 경우에도 잠금 경합이 발생할 수 있습니다. 예를 들어, 동시에 여러 트랜잭션이 동일한 데이터를 수정하려고 할 때, 데이터베이스 시스템은 잠금을 통해 일관성을 유지하려고 합니다. 그러나 이러한 잠금은 경합이 발생할 수 있는 원인이 될 수 있습니다.

시스템 잠금 경합은 주로 데이터베이스에서 발생하는 경우가 많습니다. 데이터베이스에서는 여러 클라이언트가 동시에 데이터를 읽거나 수정하려고 할 때 잠금을 사용하여 일관성을 보장합니다. 일반적으로 다음과 같은 방식으로 잠금을 사용합니다:

  1. 테이블 레벨 잠금: 전체 테이블을 잠근다. 동시에 여러 작업이 실행될 때 성능 저하를 일으킬 수 있습니다.
  2. 행 레벨 잠금: 특정 행을 잠근다. 더 작은 범위의 잠금으로 성능 개선을 이끌 수 있지만, 여전히 동시에 여러 작업이 동일한 행에 접근하면 잠금 경합이 발생할 수 있습니다.
  3. 페이지 레벨 잠금: 특정 페이지를 잠근다. 행 레벨 잠금보다 범위가 크기 때문에 동시에 접근할 수 있는 작업의 수가 늘어날 수 있습니다. 그러나 여전히 동일한 페이지에 접근하는 작업이 동시에 실행될 경우 잠금 경합이 발생할 수 있습니다.

잠금 경합을 최소화하고 성능을 향상시키기 위해 데이터베이스 시스템은 다양한 기술과 전략을 사용합니다. 몇 가지 일반적인 접근 방법은 다음과 같습니다:

  1. 트랜잭션 격리 수준 조정: 트랜잭션 격리 수준을 조정하여 잠금 경합을 줄일 수 있습니다. 더 높은 격리 수준을 선택하면 잠금 충돌 가능성이 줄어들지만, 동시성 제어 비용이 더 커질 수 있습니다. 따라서, 최적의 격리 수준을 선택하는 것이 중요합니다.
  2. 교착 상태 탐지와 해결: 교착 상태(deadlock)는 여러 작업이 상호간에 필요한 잠금을 소유한 채로 서로 기다리는 상태를 말합니다. 데이터베이스 시스템은 교착 상태를 탐지하고 해결하기 위한 알고리즘을 사용하여 잠금 경합을 해소할 수 있습니다.
  3. 인덱스 최적화: 데이터베이스 인덱스를 적절하게 설계하고 최적화하여 잠금 경합을 줄일 수 있습니다. 인덱스를 효율적으로 사용하면 데이터 검색이 빨라지고, 동시에 여러 작업이 동일한 데이터에 접근할 가능성이 줄어듭니다.
  4. 파티셔닝과 샤딩: 데이터베이스의 파티셔닝과 샤딩은 데이터를 여러 개의 논리적 또는 물리적 파티션으로 분할하는 기술입니다. 이를 통해 데이터베이스에 대한 부하를 분산시키고 잠금 경합을 감소시킬 수 있습니다.
  5. 비관적 또는 낙관적 잠금 방식 선택: 비관적 잠금은 작업이 시작되기 전에 모든 필요한 잠금을 획득하는 방식입니다. 반면에 낙관적 잠금은 작업이 진행되는 도중 충돌이 발생했을 경우에만 잠금을 획득하는 방식입니다. 적절한 잠금 방식을 선택하여 잠금 경합을 최소화할 수 있습니다.
  6. 캐시 사용: 데이터베이스 조회 작업의 성능을 향상시키기 위해 캐시를 사용할 수 있습니다. 캐시는 반복적으로 요청되는 데이터를 메모리에 저장하여 재사용하는 것이며, 데이터베이스에서의 조회 작업에 대한 잠금 경합을 줄일 수 있습니다.
  7. 분산 데이터베이스: 데이터베이스 시스템을 분산하여 여러 서버에 데이터를 저장하고 처리하는 방식을 사용할 수 있습니다. 분산 데이터베이스는 데이터의 복제와 파티셔닝을 통해 잠금 경합을 분산시키고 처리 성능을 향상시킬 수 있습니다.
  8. 오프로딩(Offloading): 데이터베이스의 부하를 줄이기 위해 일부 작업을 데이터베이스 밖으로 이동시키는 방법을 사용할 수 있습니다. 예를 들어, 캐싱, 검색 엔진, 메시지 큐 등을 활용하여 데이터베이스로부터 일부 작업을 분리할 수 있습니다. 이를 통해 데이터베이스에 대한 잠금 경합을 감소시키고 성능을 향상시킬 수 있습니다.

위의 방법들은 데이터베이스에서의 잠금 경합을 줄이고 성능을 향상시키기 위해 사용되는 일부 전략입니다. 그러나 각 상황과 요구사항에 따라 적합한 방법을 선택해야 합니다. 데이터베이스 설계, 인덱스 구성, 쿼리 최적화 등의 측면에서도 최적화 작업을 수행하여 잠금 경합을 최소화하고 성능을 향상시킬 수 있습니다.

 

용어 정리

* Troughput

시간 당 처리량을 의미함
ex) 1초에 처리하는 HTTP 요청 수 (RPS)
      네트워크로 전송외는 데이터 전송 속도 (동영상 스트리밍 서비스와 같이 대역폭이 중요한 경우)

 

* Latency

처리 시간을 의미함
인터넷 환경, 브라우저 등의 개별 환경에 대한 변수가 존재
시스템이 요청을 받고 응답을 줄 때까지의 시간 (네트워크 상황을 고려해야 할 수 도 있음)

대기시간을 포함한 각 하위 시스템 처리 시간의 총합으로 계산

-> 서울-부산 간 Latency : 각 구간의 소요 시간 합계인 5시간

-> 서울-부산 간 Throughput : 각 구간에 도달하는 차량 대수 중 최소값인 800대/시간