Qdrant - Vector Database
gRPC: высокопроизводительный протокол
Индексация 1 миллиона векторов через REST: 11 минут. Через gRPC: 3.5 минуты. Это разница между ночным батч-джобом и приемлемым временем индексации. Три строки кода для переключения протокола.
- **Batch indexing pipeline:** еженощная загрузка 500k новых векторов через gRPC — в 3x быстрее чем REST, укладывается в maintenance window
- **High-throughput microservices:** gRPC между сервисами в Kubernetes — binary protocol + HTTP/2 = меньше сетевого трафика и CPU
- **Real-time streaming:** gRPC bidirectional streaming для live обновления векторов в real-time системах (trading, fraud detection)
Предварительные знания
gRPC vs REST: почему gRPC быстрее
**gRPC** - это RPC фреймворк от Google использующий **Protocol Buffers** (бинарная сериализация) и **HTTP/2** (мультиплексирование, stream). REST использует JSON + HTTP/1.1. Разница в производительности: - **Protobuf vs JSON:** бинарный формат в 3-10x меньше по размеру, быстрее сериализация/десериализация - **HTTP/2 мультиплексирование:** несколько запросов через одно TCP соединение без head-of-line blocking - **Меньше overhead:** нет парсинга JSON, нет text encoding Реальные числа при bulk upsert в Qdrant: - REST: ~15,000 векторов/сек (512 dim) - gRPC: ~45,000 векторов/сек (512 dim) **Порты Qdrant:** - `6333` - REST API (HTTP/1.1 и HTTP/2 с TLS) - `6334` - gRPC API
| Характеристика | REST (HTTP+JSON) | gRPC (Protobuf+HTTP/2) |
|---|---|---|
| Протокол | HTTP/1.1 / HTTP/2 | HTTP/2 |
| Формат данных | JSON (текст) | Protobuf (бинарный) |
| Размер payload | Baseline | 3-5x меньше |
| Latency | Baseline | ~20-30% ниже |
| Throughput (bulk) | Baseline | ~3-5x выше |
| Streaming | Нет (polling/SSE) | Bidirectional streaming |
| Debugging | Простой (curl, Postman) | Сложнее (grpcurl) |
| Когда выбрать | API, WebApp, простой сервис | High-throughput, microservices |
**Когда REST достаточно:** для большинства приложений (интерактивный поиск, <= 10k документов/час) REST + JSON абсолютно нормален. gRPC даёт значимый выигрыш только при **высоком throughput** (bulk indexing, real-time streaming данных). Не оптимизируй преждевременно - начни с REST, переключись на gRPC когда появится bottleneck.
Приложение для семантического поиска по резюме. 500 пользователей делают поиск 100 раз/день. Раз в неделю загружается 50,000 новых резюме (bulk indexing). Какой протокол использовать?
TypeScript gRPC клиент: установка и операции
Qdrant предоставляет отдельный пакет для gRPC: **`@qdrant/js-client-grpc`**. API похож на REST клиент но с gRPC под капотом. Клиент использует `@grpc/grpc-js` и `@grpc/proto-loader` для работы с protobuf определениями Qdrant.
**Бенчмарк bulk upsert:** 100,000 векторов (512 dim) на локальном Qdrant. REST: ~65 секунд (batch 256). gRPC: ~22 секунды (batch 500). Разница: **3x ускорение** при bulk операциях. Для interactive search (1 запрос) разница в latency: REST ~8ms, gRPC ~6ms - незначительна для пользователя.
gRPC клиент падает с ошибкой `DEADLINE_EXCEEDED` при upsert больших batch. Что это значит?
gRPC в production: pooling, retry, бенчмарки
**Production gRPC** требует настройки connection management, retry logic и мониторинга. В отличие от REST где каждый запрос независим, gRPC использует persistent HTTP/2 соединения - нужно управлять их жизненным циклом.
**Connection pooling в gRPC:** HTTP/2 мультиплексирует несколько запросов через одно TCP соединение. Один `QdrantClient` = один HTTP/2 channel с автоматическим мультиплексированием. Для максимального throughput при concurrent requests - создать пул из 2-4 клиентов и распределять запросы round-robin. Больше 4-8 клиентов не даёт прироста - bottleneck переходит на сторону Qdrant сервера.
«gRPC всегда быстрее REST - нужно всегда использовать gRPC»
gRPC быстрее при bulk операциях (3-5x throughput). Для single requests разница в latency: 6ms vs 8ms - незаметна пользователю. REST проще в разработке и дебаггинге.
Overhead gRPC vs REST: protobuf сериализация быстрее JSON на 5-10x, но для маленьких payload (один поиск) абсолютная разница - микросекунды. HTTP/2 connection reuse значим при высоком throughput. При 100k vectors bulk: JSON = 50MB, protobuf = 15MB → 3x меньше сетевого трафика → 3x быстрее при network-bound workload.
NestJS сервис делает 1000 concurrent gRPC поисков в секунду к Qdrant. Один QdrantClient (gRPC) vs пул из 5 клиентов - что даст лучший throughput?
Итоги
- **gRPC порт 6334** (REST: 6333). Пакет `@qdrant/js-client-grpc`. API идентичен REST клиенту по методам.
- **3-5x throughput** при bulk upsert благодаря бинарному protobuf + HTTP/2 мультиплексированию.
- **Retry logic:** gRPC status codes (NOT_FOUND, UNAUTHENTICATED, DEADLINE_EXCEEDED) вместо HTTP кодов. Exponential backoff для transient ошибок.
- **Connection pool:** 2-4 параллельных клиента для высокого concurrent throughput. Один клиент = одно HTTP/2 соединение с мультиплексированием.
- **Когда REST достаточно:** interactive search, < 50k vectors/hour, team без gRPC опыта. Переключайся на gRPC когда REST стал bottleneck.
Что дальше
Освоили высокопроизводительный gRPC. Финальная тема - Matryoshka Representation Learning: передовая техника для экономии памяти и ускорения поиска.
- Matryoshka embeddings (MRL) — gRPC + MRL two-stage retrieval = максимальная производительность при высоком качестве
- Квантизация векторов — gRPC + квантизация = double boost производительности для bulk операций
- Security и Auth — gRPC + TLS + API key - полный production стек безопасности
Вопросы для размышления
- gRPC клиент в NestJS: как правильно реализовать как @Global() singleton с connection pooling? Нужен ли отдельный GrpcModule или достаточно расширить существующий QdrantModule?
- Как измерить является ли JSON сериализация или сеть bottleneck при REST? Какие метрики использовать для обоснования перехода на gRPC?
- gRPC streaming позволяет передавать векторы по одному по мере их генерации. Как это применимо к real-time индексации? Какой trade-off vs batch upsert?