Bối cảnh thực tế: Khi server AI sập lúc 2 giờ sáng vì vector database ngốn RAM
2 giờ 15 phút sáng. Tiếng chuông PagerDuty dồn dập kéo mình ra khỏi giấc ngủ.
Hệ thống RAG tra cứu tài liệu nội bộ phục vụ ca làm việc của thị trường Mỹ vừa tê liệt. API latency từ mức 60ms nhảy vọt lên 18.000ms rồi sập hẳn với lỗi 504 Gateway Timeout. Mở terminal SSH vào server, lệnh top hiện ngay thủ phạm: service vector database cũ viết bằng Python đang ngốn trọn 32GB RAM vật lý. Swap tràn 100%. Linux OOM Killer chuẩn bị gõ đầu tiến trình chính.
Đó là cái giá đắt cho việc chọn sai engine lưu trữ embeddings.
Nhiều team khi mới dựng pipeline RAG thường chọn giải pháp nhanh: dùng ChromaDB in-memory, Faiss dựng tạm, hoặc cụm Milvus standalone khá cồng kềnh. Khi dữ liệu chỉ dừng ở vài chục nghìn chunk, hệ thống chạy rất êm. Nhưng khi kho tri thức phình lên 500.000 vector (1536 chiều từ OpenAI) kèm payload phân quyền phức tạp, rắc rối lập tức ập đến. Garbage Collector (GC) của Python dọn không kịp. Hiện tượng stop-the-world xảy ra liên tục, đẩy CPU lên 100% và kéo sập toàn bộ cụm search.
Ngay sau sự cố đó, team quyết định đập đi xây lại storage layer và chuyển sang Qdrant.
Điểm khác biệt nằm ở kiến trúc: Qdrant được viết hoàn toàn bằng Rust. Không Garbage Collector. Không runtime ảo hóa. Qdrant quản lý bộ nhớ trực tiếp, hỗ trợ cơ chế Memory-Mapped Files (mmap), tập lệnh SIMD và thuật toán HNSW tối ưu ở tầng phần cứng.
Con số thực tế chứng minh quyết định này hoàn toàn đúng đắn. Với cùng 500.000 vector 1536 chiều, một in-memory engine ngốn từ 6GB đến 8GB RAM chỉ để giữ index. Chuyển sang Qdrant với cấu hình on_disk: true, RAM chỉ duy trì ổn định ở mức 1,2GB đến 1,8GB trên một VPS 4 core 8GB RAM. P95 latency cho các truy vấn Semantic Search kèm metadata filter vẫn đạt dưới 15ms.
Cài đặt: Triển khai Qdrant Docker chuẩn Production
Đừng bao giờ gõ một lệnh docker run bừa bãi trên production.
Nếu không map volume cẩn thận hoặc thiếu giới hạn tài nguyên, container khởi động lại sẽ ép Qdrant index lại dữ liệu từ đầu. Việc này có thể ngốn hàng giờ đồng hồ nếu kho tài liệu lớn.
Đầu tiên, bạn cần chuẩn bị thư mục lưu data và snapshots ngay trên host với đúng phân quyền UID của container:
sudo mkdir -p /opt/qdrant/storage /opt/qdrant/snapshots
sudo chown -R 1000:1000 /opt/qdrant
cd /opt/qdrant
Tạo file docker-compose.yml để cố định phiên bản, mở cổng REST (6333), gRPC (6334) và bật API key bảo vệ dữ liệu:
version: '3.8'
services:
qdrant:
image: qdrant/qdrant:v1.11.0
container_name: qdrant_engine
restart: always
ports:
- "6333:6333" # REST API & Web Dashboard
- "6334:6334" # gRPC API tốc độ cao
environment:
- QDRANT__SERVICE__API_KEY=Secr3t_Pr0d_Key_2026
- QDRANT__STORAGE__STORAGE_PATH=/qdrant/storage
- QDRANT__STORAGE__SNAPSHOTS_PATH=/qdrant/snapshots
volumes:
- ./storage:/qdrant/storage:z
- ./snapshots:/qdrant/snapshots:z
- ./config.yaml:/qdrant/config/production.yaml:ro
ulimits:
nofile:
soft: 65535
hard: 65535
deploy:
resources:
limits:
memory: 6G
reservations:
memory: 2G
Khởi chạy service ở chế độ background:
docker compose up -d
docker compose ps
Container báo trạng thái Up là mọi thứ đã thông suốt. Bạn có thể mở ngay http://localhost:6333/dashboard trên trình duyệt, nhập API key và quản lý collection qua Web UI trực quan.
Cấu hình chi tiết: Tinh chỉnh HNSW, mmap và Collection cho RAG
Mặc định, Qdrant giữ toàn bộ vector trên RAM để tối ưu tốc độ đọc.
Chiến lược này hợp lý nếu ngân sách hạ tầng của bạn thoải mái. Nhưng với server dung lượng RAM vừa phải (8GB – 16GB), bạn buộc phải ép vector payload và index HNSW xuống ổ SSD qua cơ chế mmap.
Tạo file cấu hình hệ thống config.yaml
Tạo file config.yaml cùng thư mục với docker-compose để giới hạn mức ăn RAM của engine Rust:
storage:
performance:
max_search_threads: 0 # 0 = Tự động dùng đúng số core CPU thực tế
service:
enable_dashboard: true
api_key: "Secr3t_Pr0d_Key_2026"
max_request_size_mb: 32
hnsw_index:
m: 16 # Số lượng liên kết mỗi node trong HNSW graph (16 là điểm cân bằng tốt)
ef_construct: 128 # Độ sâu tìm kiếm khi build index
full_scan_threshold: 10000
on_disk: true # Chuyển HNSW graph xuống disk để giải phóng RAM
Khởi tạo Collection tối ưu hóa cho Embedding Model
Mô hình embedding phổ biến hiện nay như text-embedding-3-small của OpenAI có dimension là 1536, còn BGE-large-en-v1.5 là 1024. Đoạn script Python dưới đây thiết lập collection với cờ on_disk=True cho cả vector lẫn payload:
from qdrant_client import QdrantClient
from qdrant_client.http import models
client = QdrantClient(
url="http://localhost:6333",
api_key="Secr3t_Pr0d_Key_2026"
)
COLLECTION_NAME = "kb_documents_rag"
if not client.collection_exists(COLLECTION_NAME):
client.create_collection(
collection_name=COLLECTION_NAME,
vectors_config=models.VectorParams(
size=1536,
distance=models.Distance.COSINE,
on_disk=True # Lưu vector embeddings trên SSD, OS tự cache qua mmap
),
hnsw_config=models.HnswConfigDiff(
m=16,
ef_construct=128,
on_disk=True
),
optimizers_config=models.OptimizersConfigDiff(
default_segment_number=4,
indexing_threshold=20000 # Gom đủ 20.000 điểm mới build index, tránh nghẽn CPU khi nạp batch lớn
)
)
print(f"Collection {COLLECTION_NAME} đã tạo thành công.")
Nạp vector và truy vấn Semantic Search cho RAG
Thực hiện chèn một điểm dữ liệu kèm payload (metadata tài liệu) và chạy thử một truy vấn kết hợp bộ lọc phân quyền:
import uuid
# Upsert payload & vector giả lập
client.upsert(
collection_name=COLLECTION_NAME,
points=[
models.PointStruct(
id=str(uuid.uuid4()),
vector=[0.012] * 1536,
payload={
"document_id": "doc_1024",
"source": "handbook_infra.pdf",
"chunk_text": "Cấu hình mmap giúp giải phóng áp lực RAM khi query vector quy mô lớn.",
"department": "engineering"
}
)
]
)
# Tìm kiếm ngữ nghĩa kết hợp lọc metadata
search_results = client.query_points(
collection_name=COLLECTION_NAME,
query=[0.012] * 1536,
query_filter=models.Filter(
must=[
models.FieldCondition(
key="department",
match=models.MatchValue(value="engineering")
)
]
),
limit=3
)
for hit in search_results.points:
print(f"Score: {hit.score:.4f} | Chunk: {hit.payload['chunk_text']}")
Giám sát & Cứu hộ: Bắt bệnh OOM và xử lý lỗi Disk Full
Đừng đợi người dùng báo lỗi mới đi kiểm tra hệ thống.
Khi Qdrant thực hiện merge các segment dữ liệu ngầm, CPU và Disk I/O có thể tăng vọt trong thời gian ngắn. Việc thiết lập metric cảnh báo sớm là bắt buộc.
Kiểm tra nhanh qua cURL
Kiểm tra trực tiếp tình trạng collection và lượng RAM mà Rust engine đang tiêu thụ:
# Kiểm tra trạng thái collection (kỳ vọng: "status": "green")
curl -s -X GET "http://localhost:6333/collections/kb_documents_rag" \
-H "api-key: Secr3t_Pr0d_Key_2026" | jq .result.status
# Đo bộ nhớ thực tế Qdrant đang chiếm dụng
curl -s -X GET "http://localhost:6333/telemetry" \
-H "api-key: Secr3t_Pr0d_Key_2026" | jq .result.app.memory
Tích hợp Prometheus Metrics
Qdrant cung cấp sẵn endpoint /metrics theo chuẩn Prometheus. Khai báo thêm job sau vào file prometheus.yml:
scrape_configs:
- job_name: 'qdrant_vector_db'
scrape_interval: 10s
metrics_path: '/metrics'
bearer_token: 'Secr3t_Pr0d_Key_2026'
static_configs:
- targets: ['qdrant_engine:6333']
Hai thông số bạn nên đặt alert đỏ trên Grafana:
app_memory_allocated_bytes: Lượng RAM thực tế Rust engine đang cấp phát. Nếu vượt 80% hạn mức container (ví dụ chạm 4,8GB trên mức giới hạn 6GB), cần giảmef_constructhoặc scale RAM server.rest_responses_duration_seconds: Độ trễ phản hồi API. Đặt cảnh báo nếu p95 vượt quá 100ms.
Quy trình xử lý sự cố khi Storage chạm ngưỡng 95%
Khi phân vùng ổ đĩa host chứa thư mục storage còn trống dưới 5%, Qdrant sẽ kích hoạt cơ chế tự vệ. Engine từ chối mọi lệnh ghi mới để tránh hỏng dữ liệu (corruption). Mọi request upsert từ pipeline RAG lúc này đều trả về lỗi 507 Insufficient Storage hoặc Storage is full.
Quy trình khắc phục trong 3 bước:
- Dọn dẹp log Docker và snapshot cũ để giải phóng dung lượng:
docker system prune -f && rm -rf /opt/qdrant/snapshots/*.snapshot - Kiểm tra lại dung lượng trống bằng lệnh
df -h /opt/qdrant/storageđể đảm bảo ổ đĩa còn trống tối thiểu 15%. - Khởi động lại container để Qdrant giải phóng trạng thái lock:
docker compose restart qdrant.
Sau khi khởi động lại, kiểm tra log bằng docker logs -f --tail 50 qdrant_engine. Khi thấy log ghi nhận Collection kb_documents_rag is green và query latency trở lại mức 12ms, bạn có thể hoàn toàn yên tâm.

