콘텐츠로 이동

로드 밸런싱 가이드

Continuum Router는 여러 백엔드에 요청을 효율적으로 분산하기 위한 고급 로드 밸런싱 기능을 제공합니다. 라우터는 각각 특정 사용 사례에 최적화된 여섯 가지 전략을 지원합니다.

목차

사용 가능한 전략

1. Round-Robin (기본)

selection_strategy: RoundRobin
  • 설명: 모든 정상 백엔드에 순차적으로 요청을 균등하게 분산
  • 사용 사례: 모든 백엔드가 유사한 기능을 가질 때 범용 부하 분산
  • 동작: 각 백엔드가 정확히 한 번의 요청을 받은 후 주기가 반복
  • 가중치 지원: 아니오 (가중치 무시)
  • 상태 관리: 최소화 (현재 백엔드 인덱스만 추적)

장점:

  • 간단하고 예측 가능
  • 공정한 분산
  • 낮은 오버헤드
  • 설정 필요 없음

단점:

  • 백엔드 성능 차이 무시
  • 요청 복잡도를 고려하지 않음
  • 느린 백엔드에 과부하를 줄 수 있음

2. Weighted Round-Robin

selection_strategy: WeightedRoundRobin

backends:
    - name: high-performance
    url: http://gpu-server:8000
    weight: 3  # 3배 더 많은 트래픽
    - name: standard
    url: http://cpu-server:8000
    weight: 1  # 기본 트래픽 수준
  • 설명: 백엔드 가중치에 비례하여 요청 분산
  • 사용 사례: 백엔드가 다른 성능 특성이나 용량을 가질 때
  • 동작: 가중치가 높은 백엔드가 비례적으로 더 많은 요청을 받음
  • 가중치 지원: 예 (필수)
  • 가중치 범위: 1-100 (권장)

장점:

  • 백엔드 기능 존중
  • 유연한 트래픽 분산
  • 부하 비율 조정 용이

단점:

  • 수동 가중치 튜닝 필요
  • 정적 가중치가 실시간 조건에 적응하지 않음

3. Least-Latency

selection_strategy: LeastLatency
  • 설명: 평균 응답 시간이 가장 낮은 백엔드로 요청 라우팅
  • 사용 사례: 프로덕션 환경에서 응답 속도 최적화
  • 동작: 응답 시간을 지속적으로 추적하고 라우팅을 그에 맞게 조정
  • 참고: 충분한 지연 시간 데이터가 수집될 때까지 round-robin으로 폴백 (일반적으로 백엔드당 10개 요청)

장점:

  • 성능을 자동으로 최적화
  • 실시간 조건에 적응
  • 수동 튜닝 필요 없음

단점:

  • 워밍업 기간 필요
  • 가장 빠른 백엔드에 부하가 집중될 수 있음
  • 일시적인 지연 시간 스파이크에 민감

4. Random

selection_strategy: Random
  • 설명: 각 요청에 대해 정상 백엔드를 무작위로 선택
  • 사용 사례: 상태 추적 없는 간단한 부하 분산
  • 동작: 각 요청이 정상 백엔드로 갈 확률이 동일
  • 장점: 상태 관리 오버헤드 없음, 무상태 워크로드에 적합

장점:

  • 상태 관리 오버헤드 없음
  • 간단한 구현
  • 무상태 워크로드에 적합
  • 자연스러운 부하 분산

단점:

  • 덜 예측 가능
  • 단기간에 불균등한 분산 가능
  • 성능 최적화 없음

5. Consistent-Hash

selection_strategy: ConsistentHash
  • 설명: 일관된 해싱을 사용하여 동일한 모델 요청이 동일한 백엔드로 가도록 보장
  • 사용 사례: 세션 어피니티가 필요하거나 캐시 효율을 극대화하려는 경우
  • 동작: 모델 이름을 해시하여 일관되게 동일한 백엔드 선택
  • 이점: 모델 캐싱 개선, 모델 로딩 오버헤드 감소

장점:

  • 캐시 효율 극대화
  • 모델 로딩 오버헤드 감소
  • 예측 가능한 라우팅
  • 상태가 있는 모델에 적합

단점:

  • 부하 불균형이 발생할 수 있음
  • 동적 스케일링에 덜 유연
  • 모델별 라우팅만 가능

6. Prefix-Aware Hash (KV 캐시 최적화)

selection_strategy: PrefixAwareHash

prefix_routing:
  enabled: true
  max_prefix_length: 1024
  load_factor_epsilon: 0.25
  virtual_nodes: 150
  anthropic_cache_control_injection: true
  • 설명: 동일한 프롬프트 접두사를 공유하는 요청을 동일한 백엔드로 라우팅하여, 추론 엔진(vLLM, SGLang, TensorRT-LLM)에서의 KV 캐시 재사용을 극대화합니다. Consistent Hashing with Bounded Loads (CHWBL)를 사용하여 핫스팟을 방지합니다.
  • 사용 사례: KV 캐시 재사용이 지연 시간에 중요한 다중 백엔드 vLLM/SGLang 배포
  • 동작: 시스템 프롬프트 또는 첫 번째 사용자 메시지에서 접두사 키(SHA256)를 추출한 다음, 해시를 사용하여 동일한 백엔드로 일관되게 라우팅합니다. CHWBL은 백엔드당 부하를 ceil(avg_load * (1 + epsilon))으로 제한하며, 백엔드가 과부하되면 링의 다음 노드로 오버플로합니다.
  • 폴백: 접두사 키를 사용할 수 없는 경우(예: 비채팅 요청) 모델 기반 ConsistentHash로 폴백합니다.

장점:

  • KV 캐시 적중 시 40-60% TTFT 감소
  • 공유 접두사 워크로드에서 40%+ 처리량 향상
  • CHWBL을 통한 자동 핫스팟 방지
  • KV 캐시 인덱스 스코어링(Tier 4)과 조합 가능

단점:

  • KV 캐시를 지원하는 백엔드 필요 (vLLM, SGLang)
  • 고유한/랜덤 프롬프트에는 효과가 적음
  • 추가 설정 필요

Prefix Key 추출

라우터는 채팅 완료 요청에서 접두사 키를 추출합니다:

  • 시스템 프롬프트가 있는 경우: SHA256(model + "\0" + "S" + system_prompt[:max_prefix_length])
  • 시스템 프롬프트가 없는 경우: SHA256(model + "\0" + "M" + first_user_message[:max_prefix_length])

이를 통해 동일한 시스템 프롬프트를 가진 요청이 동일한 백엔드로 라우팅되며, 모델 이름이 크로스 모델 충돌을 방지합니다.

CHWBL 로드 밸런싱

선호하는 백엔드의 인플라이트 요청 수가 부하 상한을 초과하면, 라우터는 해시 링을 시계 방향으로 탐색하여 다음 적격 백엔드를 찾습니다:

load_cap = ceil(average_in_flight * (1 + epsilon))

기본 epsilon = 0.25에서 백엔드는 평균 부하보다 최대 25% 더 많은 요청을 처리할 수 있으며, 이를 초과하면 오버플로됩니다. epsilon 값이 낮을수록 더 엄격한 균형을 제공하고, 높을수록 더 많은 접두사 어피니티를 유지합니다.

KV 캐시 인덱스 통합 (Tier 4)

KV 캐시 인덱스를 사용할 수 있는 경우, 라우터는 실시간 캐시 상태 데이터를 사용하여 더욱 정밀한 라우팅 결정을 내릴 수 있습니다. KvOverlapScorerPrefixAwareHash 전략 전에 실행되며, 실제 캐시된 토큰 오버랩을 기반으로 백엔드를 선택합니다:

final_score = overlap_weight * overlap_score + load_weight * (1 - load_ratio) + health_weight * health_score

최고 점수가 최소 임계값(기본값: 0.3)을 초과하면, 스코어러가 해당 백엔드를 직접 선택합니다. 그렇지 않으면 PrefixAwareHash 전략이 인계합니다. 자세한 내용은 KV 캐시 아키텍처를 참조하세요.

설정 예제

고성능 설정

최저 지연 시간에 최적화:

# 자동으로 가장 빠른 백엔드로 라우팅
selection_strategy: LeastLatency

backends:
    - name: local-gpu
    url: http://localhost:8000
    models: ["llama3", "mistral"]
    health_check:
      interval: 10s  # 정확한 지연 시간 데이터를 위한 잦은 확인
    - name: remote-gpu
    url: http://gpu-cluster:8000
    models: ["llama3", "mistral"]
    health_check:
      interval: 10s

가중치 기반 분산

서버 용량에 기반한 부하 분산:

selection_strategy: WeightedRoundRobin

backends:
    - name: powerful-server
    url: http://high-end:8000
    weight: 5  # 5배 더 많은 트래픽 처리
    models: ["gpt-4", "claude-opus"]

    - name: medium-server
    url: http://medium:8000
    weight: 2  # 2배 기본 트래픽 처리
    models: ["gpt-3.5-turbo", "claude-sonnet"]

    - name: basic-server
    url: http://basic:8000
    weight: 1  # 기본 트래픽 수준
    models: ["gpt-3.5-turbo"]

캐시 최적화 설정

모델 캐시 적중률 극대화:

selection_strategy: ConsistentHash

# 캐시 효율을 위해 모델이 항상 동일한 백엔드로 이동
backends:
    - name: backend-1
    url: http://server1:8000
    models: ["gpt-4", "gpt-3.5-turbo"]

    - name: backend-2
    url: http://server2:8000
    models: ["gpt-4", "gpt-3.5-turbo"]

    - name: backend-3
    url: http://server3:8000
    models: ["claude-opus", "claude-sonnet"]

폴백을 포함한 혼합 전략

routing:
  strategy: LeastLatency
  fallback_strategy: RoundRobin  # 지연 시간 데이터가 불충분할 때 사용

  # 특정 모델에 대한 오버라이드
  model_overrides:
    "gpt-4": ConsistentHash  # GPT-4는 항상 동일한 백엔드 사용
    "llama3": WeightedRoundRobin  # 가중치 기반으로 분산

backends:
    - name: primary
    url: http://primary:8000
    weight: 3
    priority: 1  # 선호 백엔드

    - name: secondary
    url: http://secondary:8000
    weight: 1
    priority: 2  # 폴백 백엔드

동적 전략 전환

환경 변수를 통한 전환

# 시작 시 전략 변경
export CONTINUUM_SELECTION_STRATEGY=LeastLatency
continuum-router --config config.yaml

설정 핫 리로드를 통한 전환

# config.yaml 업데이트
sed -i 's/selection_strategy: .*/selection_strategy: WeightedRoundRobin/' config.yaml

# 라우터가 자동으로 설정을 다시 로드

현재 전략 확인

# 로드 밸런싱 전략을 포함한 현재 설정 보기
curl http://localhost:8080/admin/config | jq '.selection_strategy'

# 전체 설정 세부 정보 보기
curl http://localhost:8080/admin/config

부하 분산 모니터링

백엔드 통계

# 백엔드 통계 확인
curl http://localhost:8080/admin/backends

응답:

{
  "backends": [
    {
      "name": "backend-1",
      "url": "http://server1:8000",
      "status": "healthy",
      "total_requests": 1523,
      "successful_requests": 1520,
      "failed_requests": 3,
      "average_latency_ms": 245,
      "p95_latency_ms": 450,
      "p99_latency_ms": 890,
      "weight": 2,
      "models_served": ["gpt-4", "gpt-3.5-turbo"],
      "last_selected": "2024-01-15T10:30:45Z"
    },
    {
      "name": "backend-2",
      "url": "http://server2:8000",
      "status": "healthy",
      "total_requests": 761,
      "successful_requests": 760,
      "failed_requests": 1,
      "average_latency_ms": 312,
      "p95_latency_ms": 520,
      "p99_latency_ms": 950,
      "weight": 1,
      "models_served": ["gpt-4", "gpt-3.5-turbo"],
      "last_selected": "2024-01-15T10:30:44Z"
    }
  ],
  "strategy": "WeightedRoundRobin",
  "total_requests": 2284,
  "distribution_ratio": {
    "backend-1": 0.667,
    "backend-2": 0.333
  }
}

Prometheus 메트릭

# 백엔드별 요청 분산
sum(rate(routing_decisions_total[5m])) by (selected_backend)

# 백엔드 선택 지연 시간
histogram_quantile(0.95, routing_backend_selection_duration_seconds)

# 로드 밸런싱 효과
stddev(rate(backend_request_total[5m]) by (backend_id))

고급 설정

헬스 기반 로드 밸런싱

health_checks:
  enabled: true
  interval: 30s
  timeout: 5s
  unhealthy_threshold: 3
  healthy_threshold: 2

  # 헬스에 따라 가중치 조정
  dynamic_weight_adjustment:
    enabled: true
    degraded_weight_factor: 0.5  # 저하 시 가중치 50% 감소

selection_strategy: WeightedRoundRobin

backends:
    - name: primary
    url: http://primary:8000
    weight: 100
    health_score_threshold:
      healthy: 0.9    # >90% 성공률
      degraded: 0.7    # 70-90% 성공률
      unhealthy: 0.0   # <70% 성공률

요청 기반 라우팅

routing:
  strategy: Custom

  # 요청 특성에 따른 라우팅
  rules:
        - condition:
        model: "gpt-4"
        max_tokens: { greater_than: 2000 }
      strategy: ConsistentHash  # 긴 요청은 동일 백엔드로

        - condition:
        model: "gpt-3.5-turbo"
        stream: true
      strategy: LeastLatency  # 스트리밍은 가장 빠른 백엔드로

        - condition:
        default: true
      strategy: WeightedRoundRobin

지리적 로드 밸런싱

routing:
  strategy: Geographic

backends:
    - name: us-west
    url: http://us-west.example.com:8000
    region: us-west
    weight: 1

    - name: us-east
    url: http://us-east.example.com:8000
    region: us-east
    weight: 1

    - name: eu-central
    url: http://eu-central.example.com:8000
    region: eu-central
    weight: 1

geographic_routing:
  detect_client_region: true
  fallback_to_nearest: true
  latency_based_selection: true

모범 사례

1. 간단하게 시작

  • 초기 배포 시 Round-Robin으로 시작
  • 성능 메트릭 모니터링
  • 관찰된 패턴에 따라 전략 전환

2. 모니터링 및 조정

  • /admin/backends를 사용하여 백엔드 성능 추적
  • 부하 불균형 주시
  • 가중치를 점진적으로 조정 (한 번에 ±10%)

3. 워크로드 고려

  • 균일한 요청: Round-Robin 또는 Random
  • 가변적인 용량: WeightedRoundRobin
  • 성능 중요: LeastLatency
  • 캐시 집약적: ConsistentHash

4. 헬스 체크 설정

  • 자동 장애 조치를 위한 헬스 체크 활성화
  • SLA에 기반한 적절한 임계값 설정
  • 중요한 백엔드에는 짧은 간격 사용

5. 전략 테스트

# 부하 분산 테스트
for i in {1..100}; do
  curl -s http://localhost:8080/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"Hi"}]}'
done

# 분산 확인
curl http://localhost:8080/admin/backends | jq '.distribution_ratio'

6. 점진적 마이그레이션

전략 변경 시: 1. 스테이징 환경에서 테스트 2. 24시간 모니터링 3. 프로덕션에 점진적으로 배포 4. 롤백을 위한 이전 설정 유지

전략 선택 가이드

전략 적합한 경우 장점 단점 사용 시기
RoundRobin 동등한 백엔드 간단, 공정한 분산 백엔드 용량 무시 기본 선택, 동질적 백엔드
WeightedRoundRobin 혼합 용량 백엔드 백엔드 기능 존중 가중치 튜닝 필요 알려진 성능 차이
LeastLatency 성능 최적화 실제 조건에 적응 워밍업 기간 필요 프로덕션 환경, SLA 중요
Random 무상태 워크로드 상태 오버헤드 없음 덜 예측 가능 간단한 배포, 테스트
ConsistentHash 캐시 최적화 캐시 적중 극대화 불균형 유발 가능 모델 집약적 워크로드, 상태가 있는 서비스
PrefixAwareHash KV 캐시 최적화 40-60% TTFT 감소 KV 캐시 백엔드 필요 공유 프롬프트를 사용하는 vLLM/SGLang

문제 해결

불균등한 부하 분산

# 전략 확인
curl http://localhost:8080/admin/config | jq '.selection_strategy'

# 백엔드 가중치 확인
curl http://localhost:8080/admin/backends | jq '.[].weight'

# 헬스 상태 확인
curl http://localhost:8080/admin/backends | jq '.[].status'

LeastLatency에서 높은 지연 시간

  • 워밍업 기간이 완료되었는지 확인
  • 지연 시간 측정이 정확한지 확인
  • 헬스 체크 빈도 증가 고려
  • 네트워크 문제 확인

ConsistentHash 불균형

  • 백엔드 간 모델 분산 검토
  • 더 많은 백엔드 추가 고려
  • 가중치 조정으로 보완
  • 캐시 적중률 모니터링

참고 문서