Как вы проектируете RAG для 10k RPS с P99 latency <200ms? Архитектура.
Краткий тезис
Проектирование RAG-системы на 10 000 запросов в секунду с задержкой P99 менее 200 мс требует распределённой многослойной архитектуры. Ключевые элементы: multi-region deployment для географической близости, semantic cache на Redis для горячих запросов, кластер Qdrant с replicas|read replicas для быстрого поиска, vLLM с batching|continuous batching для эффективного инференса на 8x H100, глобальный балансировщик с consistent hashing по user_id и автомасштабирование LLM реплик по GPU utilization. Такая архитектура позволяет выдерживать пиковую нагрузку при соблюдении жёсткого SLA по latency.
1. Термины и требования
RPS (Requests Per Second) — количество запросов, которое система обрабатывает за секунду. 10k RPS — это высокая нагрузка, характерная для крупных продуктов (поиск, чат-боты с миллионами пользователей).
P99 latency — задержка, которую не превышают 99% запросов. Если P99 < 200 мс, это означает, что лишь 1% запросов может быть медленнее 200 мс. Такой SLA типичен для real-time приложений.
RAG pipeline состоит из этапов: приём запроса → кэш (опционально) → retrieval из векторной БД → формирование промпта → генерация ответа LLM → постобработка. Каждый этап вносит свою задержку. Для достижения P99 < 200 мс необходимо уложить latency каждого этапа в бюджет.
| Этап | Типичная latency | Цель для 200ms |
|---|---|---|
| Сетевое взаимодействие | 1-5 ms | < 10 ms |
| Semantic cache lookup | < 1 ms | < 5 ms |
| Retrieval (Qdrant) | 5-20 ms | < 30 ms |
| LLM inference (vLLM) | 50-150 ms | < 150 ms |
| Постобработка | < 1 ms | < 5 ms |
| Итого | < 200 ms |
2. Multi-region deployment и глобальная балансировка
Размещаем инфраструктуру в нескольких регионах: us-east, eu-west, ap-southeast. Это снижает сетевую задержку для пользователей из разных частей света. Используем глобальный балансировщик нагрузки (например, AWS Global Accelerator или Cloudflare) с consistent hashing по user_id. Consistent hashing гарантирует, что запросы одного пользователя попадают в один и тот же регион и на одни и те же кэш/БД ноды, что повышает cache hit ratio и упрощает управление состоянием.
Термин: Consistent hashing — метод распределения запросов, при котором добавление или удаление сервера затрагивает минимальное количество ключей. В нашем случае ключ — user_id, что обеспечивает стабильность маршрутизации.
3. Semantic cache (Redis)
Semantic cache хранит ответы на часто задаваемые вопросы. В отличие от обычного кэша по точному совпадению, semantic cache использует эмбеддинги запроса и ищет семантически похожие. Если найден похожий запрос с высокой косинусной близостью (порог 0.95), возвращаем закэшированный ответ, минуя retrieval и LLM.
Реализация: Redis с модулем RediSearch для векторного поиска. Храним пары (эмбеддинг запроса, ответ). Для каждого входящего запроса вычисляем эмбеддинг (можно лёгкой моделью, например, all-MiniLM-L6-v2) и ищем top-1 в Redis. Если similarity > threshold, возвращаем ответ.
Cache hit ratio для горячих запросов может достигать 30-50%, что существенно снижает нагрузку на retrieval и LLM.
4. Векторная БД: Qdrant cluster с read replicas
Для retrieval используем Qdrant — высокопроизводительную векторную БД с поддержкой шардирования и репликации. Разворачиваем кластер из 3+ нод с read replicas. Write-ноды принимают обновления индекса, read replicas обслуживают запросы на чтение. Это позволяет горизонтально масштабировать retrieval.
Шардирование по user_id или по типу контента. Каждый шард хранит часть векторов. Балансировка запросов между read replicas через внутренний балансировщик (например, HAProxy или встроенный Qdrant).
Для latency < 30 ms используем HNSW (Hierarchical Navigable Small World) индекс с параметрами: ef_construct=200, M=16. Это даёт высокую скорость поиска при небольшой потере точности.
5. LLM инференс: vLLM с continuous batching
Для генерации ответа используем vLLM — библиотеку для эффективного инференса LLM. Continuous batching позволяет обрабатывать несколько запросов параллельно на одном GPU, динамически формируя батчи. Это увеличивает throughput и снижает latency.
Разворачиваем 8x H100 (NVIDIA H100 Tensor Core GPU) с 80GB памяти каждая. Этого достаточно для модели размером 70B параметров (например, Llama-3-70B) в 4-bit квантизации (GPTQ или AWQ). vLLM поддерживает PagedAttention для эффективного управления KV-кэшем, что снижает потребление памяти.
Latency budget для LLM: 150 мс. При continuous batching и оптимизациях (flash attention, tensor parallelism) можно достичь latency 100-120 мс для batch size 8-16.
6. Consistent hashing для балансировки LLM реплик
Для распределения запросов между репликами LLM используем consistent hashing по user_id. Это гарантирует, что запросы одного пользователя попадают на одну и ту же реплику, что улучшает cache hit для KV-кэша (vLLM поддерживает prefix caching). Также это упрощает мониторинг и дебаггинг.
Пример реализации на Python (упрощённо):
import hashlib
class ConsistentHashRing:
def __init__(self, nodes, replicas=100):
self.replicas = replicas
self.ring = {}
self.sorted_keys = []
for node in nodes:
for i in range(replicas):
key = self._hash(f"{node}:{i}")
self.ring[key] = node
self.sorted_keys.append(key)
self.sorted_keys.sort()
def _hash(self, key):
return int(hashlib.md5(key.encode()).hexdigest(), 16)
def get_node(self, user_id):
if not self.ring:
return None
hash_val = self._hash(str(user_id))
for key in self.sorted_keys:
if hash_val <= key:
return self.ring[key]
return self.ring[self.sorted_keys[0]]
7. Автомасштабирование LLM реплик
Мониторим GPU utilization каждой реплики. Если средняя загрузка GPU превышает 70% в течение 5 минут, добавляем новую реплику. Если падает ниже 30% — удаляем. Используем Kubernetes HPA (Horizontal Pod Autoscaler) с кастомными метриками от Prometheus.
Термин: GPU utilization — процент времени, когда GPU занят вычислениями. Высокая утилизация (80-90%) оптимальна для throughput, но для low latency лучше держать 50-70%, чтобы оставался запас для пиков.
8. Предсказание ресурсов
Для планирования инфраструктуры оцениваем необходимые ресурсы:
- GPU: 8x H100. Одна H100 может обрабатывать ~1500 RPS для модели 70B (с continuous batching). Для 10k RPS нужно 7-8 GPU. С запасом — 8.
- Memory: 512 GB RAM для серверов приложений, Redis, Qdrant. Qdrant хранит векторы в RAM для быстрого доступа. Для 10M векторов размером 768 dim (float32) нужно ~30 GB. С индексами и репликами — 100 GB.
- Storage: 2 TB NVMe SSD для логов, чекпоинтов моделей, временных данных.
9. Мониторинг и алертинг
Критические метрики:
- P99 latency каждого этапа (сеть, кэш, retrieval, LLM)
- Throughput (RPS) на каждом компоненте
- Cache hit ratio semantic cache
- GPU utilization и queue depth vLLM
- Error rate (timeout, 5xx)
Настраиваем алерты: если P99 latency > 200 ms в течение 1 минуты — эскалация. Используем Prometheus + Grafana для дашбордов.
Пет-проект для закрепления
Задача: Спроектировать и развернуть прототип RAG-системы на 1000 RPS с P99 < 300 ms (упрощённо) с использованием Terraform, Kubernetes, Qdrant, Redis, vLLM.
Инструменты:
- Terraform для provisioning облачных ресурсов (AWS EKS, RDS для метаданных)
- Kubernetes (EKS) для оркестрации микросервисов
- Qdrant Operator для развертывания кластера
- Redis Enterprise или OSS с модулем RediSearch
- vLLM с Docker образом
- Locust для нагрузочного тестирования
Шаги:
- Развернуть Kubernetes кластер в одном регионе.
- Установить Qdrant cluster (3 ноды) и Redis.
- Развернуть vLLM с моделью (например, Llama-3-8B для тестов).
- Написать сервис-оркестратор (FastAPI), который принимает запросы, проверяет кэш, вызывает retrieval и LLM.
- Настроить HPA для vLLM по GPU utilization.
- Запустить Locust с 1000 concurrent users и измерить P99 latency.
- Оптимизировать параметры (batch size, threshold кэша, количество реплик).
Ожидаемый результат: Работающая система, выдерживающая 1000 RPS с P99 < 300 ms. Дашборд Grafana с метриками.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 7 | Как вы уменьшаете latency RAG-системы (время ответа)? |
| 8 | Как вы используете кэширование в RAG? |
| 12 | Как вы масштабируете векторную БД? |
| 15 | Как вы деплоите LLM для инференса? |
| 20 | Как вы проектируете multi-region RAG? |
| 30 | Как вы настраиваете автомасштабирование? |
Навигация
- Предыдущий: 402
- Следующий: 404
- Индекс: 00. Индекс разборов