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?

Навигация