이코에코(Eco²)/Event Streams & Scaling

이코에코(Eco²) Streams & Scaling for SSE #11: Scan API 부하 테스트 (2)

mango_fr 2025. 12. 29. 00:23

VU 300 부하 한계점 분석

테스트 데이터 비교 (250 VU vs 300 VU)

요청 수 1,754 1,732 -22건 (-1.3%)
완료율 99.94% 99.94% 동일
Throughput 417.6 req/m 402 req/m -0.22 (-3.2%)
E2E p95 40.5초 48.5초 +8초 (+20%)
E2E avg 30.2초 37.6초 +7.4초 (+25%)
테스트 시간 252초 256.8초 +4.8초

부하 포화 징후

┌────────────────────────────────────────────────────────────────────────┐
│  📊 Little's Law 기반 분석                                                │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  250 VU: Throughput = 250 / 40.5초 = 6.17 req/s (실측 6.96)              │
│  300 VU: Throughput = 300 / 48.5초 = 6.19 req/s (실측 6.74)              │
│                                                                        │
│  → VU 20% 증가 시 이론적으로 Throughput도 증가해야 함                         │
│  → 실제로는 오히려 3.2% 감소 = 처리 시간 증가 관측, 시스템 포화 상태 진입            │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

포화 판단 근거

  1. 처리량 역전 현상
    • VU 증가(+20%)에도 불구하고 throughput 감소(-3.2%)
    • 시스템이 물리적 부하에 도달해 연산량 저하, 더 많은 요청을 받아도 빠르게 처리하지 못함
    • 노드 수평 확장 필요, 컴포넌트별 단일 노드 한계 지점 도출을 위해 노드 HA는 적용하지 않음
  2. 응답 시간 급증
    • E2E p95: 40.5초 → 48.5초 (+20%)
    • 큐 대기 시간 증가로 인한 지연
  3. 요청 수 감소
    • 같은 3분 동안 22건 더 적게 처리
    • 각 VU의 iteration 횟수 감소
  4. 성공률 유지
    • 99.94%로 동일 = 아직 에러 발생 X
    • 시스템은 느려지지만 실패하지 않음

로컬 Mac 스펙 분석

시스템 사양

CPU Apple M3
코어 8코어
메모리 16 GB
FD Limit 1,048,575 

k6 클라이언트 VU 한계 추정

CPU 기반 8코어 × 200 VU 1,600 VU
메모리 기반 16GB ÷ 10MB 1,600 VU
FD 기반 1M ÷ 10 100,000+ VU

 

┌────────────────────────────────────────────────────────────────────────┐
│  🖥️  로컬 k6 클라이언트 한계: ~1,600 VU                               │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  ✅ 500 VU 테스트: 문제 없음                                               │
│  ✅ 1000 VU 테스트: 가능                                                  │
│  ⚠️  1500+ VU: 주의 필요                                                  │
│                                                                        │
│  💡 현재 병목은 서버 측 (k8s-worker-ai 2 cores)                            │
│     로컬 Mac은 충분히 여유 있음                                             │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

VU 400 부하 테스트 리포트

https://snapshots.raintank.io/dashboard/snapshot/frzezh23ZWCrpiWNprpEtv3tFsdTEouI

 

Grafana

If you're seeing this Grafana has failed to load its application files 1. This could be caused by your reverse proxy settings. 2. If you host grafana under subpath make sure your grafana.ini root_url setting includes subpath. If not using a reverse proxy m

snapshots.raintank.io

 
 

테스트 환경

 

  • 시간: 2025-12-28 22:46:46 ~ 22:54:40 KST (약 8분)
  • VUs: 400 (동시 사용자)
  • 테스트 방식: POST → Polling 방식

K6 테스트 결과

성공률 99.6% (1,894/1,901) ✅ 1901 요청 중 7건 실패
완료율 98.9% (1,790/1,810) ✅ 여전히 높음
보상 수령률 95.2% (1,715/1,790) ⚠️ 소폭 하락
Scan API p95 207ms ⚠️ 증가 (300VU: 83ms)
완료 시간 p95 62.0초 ⚠️ 임계치(60초) 초과
E2E p95 62.2초 ⚠️ 증가 (300VU: 48초)
Throughput 422.2 req/m ✅ 최고치
Polling 요청 36,583건 약 20회/job

KEDA Scaling 이벤트

시간 이벤트 상세
테스트 시작 scan-worker 1→3 scan.{vision, answer, rule} 큐 기반 트리거
+24초 scan-api 1→2 CPU 사용률 기반
+54초 scan-api 2→3 CPU 사용률 기반
테스트 종료 scan-worker 3→1 메트릭 정상화

 


Redis Streams 상태 (테스트 후)

scan:events:0: 4,860
scan:events:1: 4,700
scan:events:2: 4,970
scan:events:3: 4,410

총: 18,940개 (균등 분배 ±6%)
Pending: 0 (모든 메시지 ACK 완료)

테스트 결과 비교 (50 ~ 400 VU)

50 685 99.7% 198 req/m 17.7초 93ms ✅ 여유
200 1,649 99.8% 367 req/m 33.2초 83ms ✅ 여유
250 1,754 99.9% 417.6 req/m 40.5초 78ms ⭐ 서비스 최적점(SLA)
300 1,732 99.9% 402 req/m 48.5초 83ms ⚠️ 포화 시작
400 1,901 98.9% 422.2 req/m 62.2초 207ms ⚠️ 한계 근접

 

┌────────────────────────────────────────────────────────────────────────┐
│  📊 400 VU 분석                                                        │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  ✅ 예상보다 좋은 결과: 98.9% 완료율 (예상 90-95%)                            │
│  ✅ Throughput 최고치: 7.12 req/s (300VU 대비 +5.6%)                      │
│  ✅ KEDA 정상 작동: scan-worker 1→3, scan-api 1→3 스케일업                 │
│                                                                        │
│  ⚠️ 경고 신호:                                                            │
│  • E2E p95 62초 (Eco² SLA 임계치 60초 초과)                                │
│  • Scan API p95 207ms (300VU 대비 2.5배 증가)                             │
│  • 완료율 98.9% (300VU 99.9% 대비 1% 하락)                                 │
│  • 실패 7건 발생 (300VU: 0건)                                             │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────────────────┐
│  🎯 단일 노드 한계점: ~400 VU                                         │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  • 400 VU에서 98.9% 완료율 유지 = 아직 안정적                        │
│  • 하지만 E2E p95 > 60초 = SLA 임계치 초과                           │
│  • Throughput은 오히려 증가 (7.12 req/s) = KEDA 스케일링 효과        │
│                                                                        │
│  📈 실제 한계:                                                        │
│  • 완료율 기준: ~450-500 VU에서 95% 이하로 하락 예상                 │
│  • SLA 기준 (E2E p95 < 60초): 300 VU가 안전 한계                     │
│                                                                        │
│  🚀 확장 전략:                                                        │
│  • Karpenter 적용 시 400 VU × 노드수 확장 가능                       │
│  • 현재 단일 노드(2 cores)에서 400 VU 처리 가능 확인                 │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

VU 500 부하 테스트

https://snapshots.raintank.io/dashboard/snapshot/dtBvLo3J2JlQ3LwWbcM6iwBJJuhboow5

 

Grafana

If you're seeing this Grafana has failed to load its application files 1. This could be caused by your reverse proxy settings. 2. If you host grafana under subpath make sure your grafana.ini root_url setting includes subpath. If not using a reverse proxy m

snapshots.raintank.io

 

테스트 환경

 

  • 시간: 2025-12-28 23:16:36 ~ 23:21:45 KST (약 5분)
  • VUs: 500 (동시 사용자)
  • 테스트 방식: POST → Polling 방식
  • 환경: 큐/스트림 청정 상태에서 시작

K6 테스트 결과

성공률 99.7% (1,984/1,990) ✅ 6건 실패
완료율 94.0% (1,629/1,733) ⚠️ 95% 이하로 하락
보상 수령률 91.2% (1,575/1,629) ⚠️ 하락
Scan API p95 154ms ⚠️ 증가 (400VU: 207ms)
완료 시간 p95 76.3초 ❌ 임계치(60초) 초과
E2E p95 76.4초 ❌ 증가 (400VU: 62초)
Throughput 438 req/m ✅ 최고치
Polling 요청 46,335건 약 28회/job


KEDA Scaling

시간 컴포넌트 스케일링 트리거
테스트 시작 scan-worker 1→3 scan.vision 10 msg+, scan.answer 10msg+, scan.rule 20msg+
+1분 scan-api 1→2 CPU 사용률
+2분 scan-api 2→3 CPU 사용률
테스트 종료 scan-worker 3→1 메트릭 정상화

 


Redis Streams 상태 (테스트 후)

scan:events:0: 4,970
scan:events:1: 4,440
scan:events:2: 4,970
scan:events:3: 5,460

총: 19,840개 (균등 분배 ±11%)

전체 부하 테스트 결과 비교 (50 ~ 500 VU)

50 685 99.7% 198 req/m 17.7초 93ms ✅ 여유
200 1,649 99.8% 367 req/m 33.2초 83ms ✅ 여유
250 1,754 99.9% 417.6 req/m 40.5초 78ms 서비스 최적점
300 1,732 99.9% 402 req/m 48.5초 83ms ⚠️ 포화 시작
400 1,901 98.9% 422.2 req/m 62.2초 207ms ⚠️ 한계 근접
500 1,990 94.0% 438 req/m 76.4초 154ms ⚠️ 완료율 하락(-5%)

한계 징후 도출

┌────────────────────────────────────────────────────────────────────────┐
│  🎯 500 VU = 단일 노드 한계점                                         │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  📉 완료율 하락                                                           │
│  • 400 VU: 98.9% → 500 VU: 94.0% (4.9%p 하락)                           │
│  • 처음으로 95% 이하로 떨어짐                                               │
│                                                                        │
│  ⏱️  응답 시간 급증                                                       │
│  • E2E p95: 62초 → 76초 (22.6% 증가)                                     │
│  • SLA 임계치(60초) 크게 초과                                              │
│                                                                        │
│  📊 Throughput은 증가                                                    │
│  • 7.37 req/s (역대 최고치)                                               │
│  • 하지만 완료율 5% 감소                                                       │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

VU 600 부하 테스트 시도

  • OpenAI API quota 초과로 테스트 진행 불가
  • quota 갱신 후 VU 600부터 이어서 진행할 예정

OpenAI API Usage

  • 이코에코 서비스용 API 키, 테스트 신뢰성을 위해 실제 모델(GPT 5.1)을 유지하며 진행
  • 소모 토큰: 1억 400만

현재 LLM API Usage Tier 

  • Tier 3으로 월 1,000$까지 호출 가능
  • 아직 Usage Limits엔 도달하지 않았으나, 개인 비용 문제로 당일 부하 테스트는 500VU에서 중단