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/completionsvs/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.
Шаги:
- Создать FastAPI-приложение с эндпоинтом
/v1/chat/completions. - Реализовать middleware, которое извлекает API-ключ из заголовка
Authorization. - Для каждого ключа проверять лимит (например, 100 req/min) через Redis.
- Если лимит превышен — возвращать 429 с заголовками
X-RateLimit-*. - Если лимит не превышен — проксировать запрос к OpenAI и возвращать ответ.
- Добавить поддержку burst (token bucket) для кратковременных всплесков.
- Написать тесты с
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. Индекс разборов