Aivaro
  • Contents
  • Questions
  • Practice
  • Wiki
  • Community materials
  • Tests
  • Search
✈Telegram @ai_varo
RUEN中文
…
Contents/Questions/#829

English translation is not available yet. Showing Russian content.

Что такое rate limiting на уровне API Gateway для LLM?

Краткий тезис

Rate limiting (ограничение скорости запросов) на уровне API Gateway — это механизм контроля интенсивности входящих запросов к LLM-сервису. Он защищает бэкенд от перегрузки, злоупотреблений и неконтролируемого роста затрат, применяя разные лимиты для пользователей, API-ключей, IP-адресов и всего кластера. Реализуется с помощью алгоритмов token bucket или sliding window на базе Redis, а при превышении лимита возвращает HTTP-статус 429 Too Many Requests с соответствующими заголовками.


1. Зачем нужен rate limiting для LLM

LLM-модели (например, GPT-4, Claude) требуют значительных вычислительных ресурсов и стоят дорого. Без rate limiting возможны:

  • Перегрузка бэкенда — один клиент может отправить тысячи запросов в секунду, исчерпав GPU-ресурсы.
  • Финансовые потери — злоумышленник или ошибочный скрипт может нагенерировать огромные счета.
  • Неравномерное распределение ресурсов — «шумные» пользователи лишают доступа остальных.
  • DDoS-атаки — целенаправленная перегрузка API.

API Gateway выступает единой точкой входа, где rate limiting применяется до того, как запрос дойдёт до LLM-инференса.


2. Уровни rate limiting

Ограничения накладываются на разные сущности, чтобы гибко управлять доступом.

УровеньТипичный лимитПример
User (пользователь)100 req/minИдентифицируется по JWT-токену или сессии.
API key (ключ)1000 req/minДля каждого зарегистрированного приложения.
IP-адрес50 req/minДля анонимных или неаутентифицированных клиентов.
Total (кластер)10000 req/minСуммарный лимит на все запросы к LLM-сервису.

Комбинирование: запрос проверяется по всем уровням. Если хотя бы один лимит превышен — возвращается 429.


3. Алгоритмы rate limiting

3.1 Token Bucket (ведро токенов)

  • Ведро вмещает B токенов.
  • Каждый запрос забирает 1 токен.
  • Токены пополняются со скоростью R токенов в секунду.
  • Если ведро пусто — запрос отклоняется.

Преимущества: допускает кратковременные всплески (burst) до размера ведра, сглаживает нагрузку.

3.2 Sliding Window (скользящее окно)

  • Фиксируется временное окно (например, 1 минута).
  • Считается количество запросов в окне.
  • Окно «скользит» с каждым запросом (точнее, учитывается вес предыдущего окна).

Реализация через Redis: храним счётчик для каждого ключа с TTL, равным размеру окна. При каждом запросе увеличиваем счётчик и проверяем, не превышен ли лимит.

3.3 Leaky Bucket (дырявое ведро)

  • Запросы поступают в очередь (ведро) с фиксированной скоростью обработки.
  • Если очередь переполнена — запросы отбрасываются.
  • Меньше подходит для burst-нагрузки, чаще используется для стабильного трафика.

4. Реализация на базе Redis

Redis — идеальное хранилище для rate limiting благодаря атомарным операциям и низкой задержке.

Пример реализации sliding window на Python с Redis:

import redis
import time

r = redis.Redis(host='localhost', port=6379, decode_responses=True)

def is_rate_limited(key: str, limit: int, window: int = 60) -> bool:
    """Проверяет, превышен ли лимит для заданного ключа.
    
    Args:
        key: уникальный идентификатор (user_id, api_key, IP)
        limit: максимальное количество запросов за окно
        window: размер окна в секундах (по умолчанию 60)
    
    Returns:
        True, если лимит превышен (запрос должен быть отклонён)
    """
    now = time.time()
    window_start = now - window
    
    # Удаляем устаревшие записи
    r.zremrangebyscore(key, 0, window_start)
    
    # Считаем количество запросов в текущем окне
    current_count = r.zcard(key)
    
    if current_count >= limit:
        return True
    
    # Добавляем текущий запрос с меткой времени
    r.zadd(key, {str(now): now})
    r.expire(key, window)  # устанавливаем TTL для автоматической очистки
    return False

Важно: для production используйте Lua-скрипты или Redis модули (например, redis-cell) для атомарности.


5. HTTP-заголовки и ответ 429

При отклонении запроса API Gateway должен возвращать стандартные заголовки, чтобы клиент мог адаптироваться.

ЗаголовокОписаниеПример
X-RateLimit-LimitМаксимальное количество запросов за окно100
X-RateLimit-RemainingОставшееся количество запросов в текущем окне45
Retry-AfterВремя (в секундах), через которое можно повторить запрос30

Тело ответа (JSON):

{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Please retry after 30 seconds.",
  "retry_after_seconds": 30
}

HTTP-статус: 429 Too Many Requests.


6. Стратегии rate limiting

  • Hard limit — жёсткое отклонение всех запросов сверх лимита.
  • Soft limit — запросы сверх лимита обрабатываются, но клиент предупреждается (например, через заголовки). Полезно для постепенного внедрения.
  • Burst allowance — разрешение кратковременных всплесков (через token bucket).
  • Adaptive rate limiting — динамическое изменение лимитов на основе текущей нагрузки бэкенда (например, загрузки GPU).

7. Rate limiting vs Throttling vs Quota

ТерминОписание
Rate limitingОграничение скорости запросов (за единицу времени).
ThrottlingБолее широкое понятие: может включать rate limiting, а также приоритизацию, отбрасывание избыточных запросов.
QuotaОграничение общего количества запросов за длительный период (день, месяц). Часто используется для биллинга.

В API Gateway для LLM обычно применяются все три: rate limiting для защиты, quota для тарификации.


8. Проблемы и best practices

Проблемы

  • Распределённые системы — если несколько экземпляров Gateway, нужно централизованное хранилище (Redis).
  • Точность — sliding window может давать погрешность на границах окон.
  • Стоимость Redis — при очень высоком RPS Redis может стать узким местом.

Best practices

  • Использовать Redis Cluster или ElastiCache для отказоустойчивости.
  • Применять Lua-скрипты для атомарных операций.
  • Логировать все случаи превышения лимита для анализа.
  • Настраивать разные лимиты для разных эндпоинтов (например, /chat/completions vs /embeddings).
  • Внедрять graceful degradation — при превышении лимита не блокировать полностью, а переводить на более дешёвую модель или очередь.

9. Пример интеграции с API Gateway (Kong / NGINX)

Kong — популярный API Gateway с плагином rate-limiting.

# Конфигурация плагина в Kong
plugins:
  - name: rate-limiting
    config:
      second: null
      minute: 100
      hour: null
      policy: redis
      redis_host: redis-cluster.example.com
      redis_port: 6379
      fault_tolerant: true
      hide_client_headers: false

NGINX — через модуль ngx_http_limit_req_module:

http {
    limit_req_zone $binary_remote_addr zone=llm_api:10m rate=50r/m;
    
    server {
        location /v1/chat/ {
            limit_req zone=llm_api burst=20 nodelay;
            proxy_pass http://llm_backend;
        }
    }
}

10. Мониторинг и алерты

Ключевые метрики для rate limiting:

  • Rate limit hits — количество отклонённых запросов (429).
  • Rate limit usage by user — топ пользователей по потреблению.
  • Latency Redis — время ответа Redis при проверке лимитов.
  • Error rate — доля 429 среди всех ответов.

Настройте алерты на резкий рост 429 (возможна DDoS-атака) или на приближение к лимиту кластера.


Пет-проект для закрепления

Задача: Реализовать rate limiting для простого LLM-прокси на FastAPI с использованием Redis и sliding window.

Инструменты: Python, FastAPI, Redis (через redis-py), httpx для проксирования запросов к OpenAI API.

Шаги:

  1. Создать FastAPI-приложение с эндпоинтом /v1/chat/completions.
  2. Реализовать middleware, которое извлекает API-ключ из заголовка Authorization.
  3. Для каждого ключа проверять лимит (например, 100 req/min) через Redis.
  4. Если лимит превышен — возвращать 429 с заголовками X-RateLimit-*.
  5. Если лимит не превышен — проксировать запрос к OpenAI и возвращать ответ.
  6. Добавить поддержку burst (token bucket) для кратковременных всплесков.
  7. Написать тесты с pytest и mock для Redis.

Ожидаемый результат: Работающий прокси-сервер, который ограничивает количество запросов для каждого API-ключа, корректно возвращает 429 и заголовки, а также логирует все события.


Связь с другими вопросами

ВопросТема
830Как настроить аутентификацию в API Gateway для LLM?
831Что такое throttling и чем отличается от rate limiting?
832Как реализовать кэширование ответов LLM на уровне API Gateway?
833Какие метрики мониторить для API Gateway LLM?
834Как обеспечить отказоустойчивость API Gateway?

Навигация

  • Предыдущий: 828
  • Следующий: 830
  • Индекс: 00. Индекс разборов