확장성 테스트 (Scalability Test)

확장성 테스트는 소프트웨어 시스템이 증가하는 부하나 규모에 얼마나 잘 대응할 수 있는지를 평가하는 성능 테스트의 한 유형이다.
이는 시스템의 확장 능력을 측정하고 검증하는 과정이다.

웹 서비스의 확장성 테스트 예시 코드:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import time
from concurrent.futures import ThreadPoolExecutor
from monitoring import SystemMonitor

class ScalabilityTest:
    def __init__(self):
        self.monitor = SystemMonitor()
        self.results = []
        
    def test_vertical_scaling(self):
        """수직적 확장성 테스트
        (단일 서버의 자원 증가에 따른 성능 변화 측정)"""
        
        # 서버 자원을 단계적으로 증가시키며 테스트
        resource_configs = [
            {"cpu_cores": 2, "memory": "2GB"},
            {"cpu_cores": 4, "memory": "4GB"},
            {"cpu_cores": 8, "memory": "8GB"}
        ]
        
        for config in resource_configs:
            # 서버 리소스 조정
            self.adjust_server_resources(config)
            
            # 성능 측정
            metrics = self.measure_performance()
            
            # 결과 기록
            self.results.append({
                "config": config,
                "metrics": metrics
            })
            
            # 선형적 확장성 검증
            self.verify_linear_scaling(config, metrics)
    
    def test_horizontal_scaling(self):
        """수평적 확장성 테스트
        (서버 수 증가에 따른 성능 변화 측정)"""
        
        # 서버 인스턴스 수를 단계적으로 증가
        for server_count in range(1, 6):
            # 서버 추가
            self.add_server_instances(server_count)
            
            # 부하 테스트 실행
            with ThreadPoolExecutor(max_workers=100) as executor:
                # 동시 요청 시뮬레이션
                futures = [
                    executor.submit(self.simulate_request)
                    for _ in range(1000)
                ]
                
                # 결과 수집
                responses = [f.result() for f in futures]
                
            # 성능 메트릭 분석
            self.analyze_scaling_metrics(server_count, responses)

특징과 목적

확장성 테스트의 주요 특징과 목적은 다음과 같다:

  1. 시스템의 확장 한계 파악
  2. 성능 병목 현상 식별
  3. 리소스 사용의 효율성 평가
  4. 미래 성장에 대한 대비 능력 검증

테스트 범위

확장성 테스트는 다음과 같은 범위를 포함한다:

  1. 사용자 수 증가에 따른 시스템 반응
  2. 데이터 볼륨 증가에 따른 처리 능력
  3. 트랜잭션 수 증가에 따른 시스템 성능
  4. 하드웨어 리소스 확장에 따른 성능 변화

수행 시점

확장성 테스트는 주로 다음 시점에 수행된다:

  1. 시스템 설계 단계에서의 초기 평가
  2. 개발 후반부의 성능 최적화 단계
  3. 대규모 사용자 유입이 예상되는 시점 전

검증 대상

주요 검증 대상은 다음과 같다:

  1. 응답 시간
  2. 처리량 (Throughput)
  3. 리소스 사용률 (CPU, 메모리, 디스크 I/O, 네트워크)
  4. 데이터베이스 성능

확장성 테스트의 종류

  1. 수직적 확장성 테스트: 단일 시스템의 리소스를 증가시켜 성능 변화를 측정

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    def test_vertical_scalability():
        """CPU와 메모리 증가에 따른 성능 테스트"""
        workload = generate_test_workload()
    
        for cpu_cores in [2, 4, 8]:
            for memory_gb in [4, 8, 16]:
                # 시스템 자원 조정
                configure_system_resources(
                    cpu_cores=cpu_cores,
                    memory_gb=memory_gb
                )
    
                # 성능 측정
                performance = measure_system_performance(workload)
    
                print(f"CPU: {cpu_cores}cores, "
                      f"Memory: {memory_gb}GB, "
                      f"Performance: {performance}")
    
  2. 수평적 확장성 테스트: 여러 시스템을 추가하여 분산 처리 능력을 평가

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    def test_horizontal_scalability():
        """서버 인스턴스 수 증가에 따른 성능 테스트"""
        base_load = 1000  # 기본 요청 수
    
        for instance_count in [1, 2, 4, 8]:
            # 서버 인스턴스 추가
            scale_out_servers(instance_count)
    
            # 부하 증가
            test_load = base_load * instance_count
    
            # 성능 측정
            throughput = measure_throughput(test_load)
            latency = measure_latency(test_load)
    
            # 선형 확장성 검증
            verify_linear_scaling(instance_count, throughput)
    

진행 방식

확장성 테스트는 다음과 같은 단계로 진행된니다:

  1. 테스트 계획 수립: 목표 설정, 시나리오 정의

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    scalability_test_plan = {
        "테스트_범위": {
            "수직적_확장": {
                "CPU": [2, 4, 8, 16],
                "메모리": ["4GB", "8GB", "16GB", "32GB"]
            },
            "수평적_확장": {
                "서버_수": [1, 2, 4, 8, 16],
                "로드밸런서": ["라운드로빈", "최소연결"]
            }
        },
        "성능_지표": [
            "처리량(TPS)",
            "응답시간",
            "자원_활용률"
        ],
        "목표_기준": {
            "선형_확장성": "80% 이상",
            "응답시간_증가": "20% 이내",
            "비용_효율성": "리소스당 성능향상 70% 이상"
        }
    }
    
  2. 초기 성능 측정: 기준점 설정

  3. 단계적 부하 증가: 사용자 수, 데이터 양, 트랜잭션 수 등을 점진적으로 증가

  4. 성능 모니터링: 각 단계에서의 시스템 반응 관찰

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    def execute_scalability_test():
        """확장성 테스트 실행"""
        try:
            # 기준 성능 측정
            baseline_metrics = measure_baseline_performance()
    
            # 단계별 확장 테스트
            for scale_level in test_plan.scale_levels:
                # 시스템 확장
                scale_system(scale_level)
    
                # 부하 생성
                generate_test_load(scale_level.expected_load)
    
                # 성능 측정
                current_metrics = measure_performance_metrics()
    
                # 확장성 분석
                analyze_scaling_efficiency(
                    baseline_metrics,
                    current_metrics,
                    scale_level
                )
    
        finally:
            # 시스템 원복
            restore_system_state()
    
  5. 결과 분석: 성능 변화 추이 분석, 병목 지점 식별

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    def analyze_scalability_results():
        """확장성 테스트 결과 분석"""
        analysis = {
            "확장성_지표": {
                "선형성": calculate_linearity_score(),
                "효율성": calculate_scaling_efficiency(),
                "비용_효율": calculate_cost_efficiency()
            },
            "병목_지점": {
                "자원_한계": identify_resource_bottlenecks(),
                "아키텍처_한계": identify_architectural_limits()
            },
            "권장사항": generate_scaling_recommendations()
        }
    
        return create_analysis_report(analysis)
    
  6. 보고서 작성: 발견된 문제점과 개선 방안 정리

확장성 테스트 수행 시 주요 고려사항

  1. 점진적 접근
    급격한 확장보다는 단계적으로 규모를 늘려가며 테스트한다.
  2. 비용 효율성 고려
    자원 증가에 따른 성능 향상과 비용을 함께 분석한다.
  3. 병목 지점 식별
    시스템의 확장을 제한하는 요소들을 찾아낸다.
  4. 자동화된 테스트
    반복적인 테스트를 자동화하여 효율성을 높인다.

예시

온라인 쇼핑몰 애플리케이션의 확장성 테스트를 예로 들어보자:

  1. 목표 설정: 현재 10,000명의 동시 접속자를 100,000명까지 확장 가능한지 검증
  2. 시나리오: 상품 검색, 장바구니 추가, 결제 프로세스 수행
  3. 테스트 실행:
    • 10,000명부터 시작하여 20,000명, 50,000명, 100,000명으로 단계적 증가
    • 각 단계에서 응답 시간, 처리량, 서버 리소스 사용률 측정
  4. 결과 분석:
    • 80,000명까지는 성능 저하 없이 처리 가능
    • 100,000명에서 데이터베이스 연결 지연 발생
  5. 개선 방안: 데이터베이스 샤딩 도입, 캐시 서버 추가

참고 및 출처