Qdrant là một Vector Database mã nguồn mở, được sử dụng phổ biến trong các hệ thống AI, chatbot, RAG (Retrieval-Augmented Generation) và tìm kiếm ngữ nghĩa.
Khi hệ thống có hàng nghìn collections và lượng dữ liệu vector lớn, việc chuyển Qdrant sang server mới không đơn giản chỉ là copy thư mục. Chúng ta cần quan tâm đến tính toàn vẹn của RocksDB, quyền truy cập, tài nguyên hệ thống, Docker và cơ chế xác thực API.
Bài viết này tổng hợp quy trình chuyển Qdrant giữa hai server Linux bằng Docker và rsync, đồng thời hướng dẫn thay đổi API Key, xử lý các lỗi thực tế như Too many open files, Resource temporarily unavailable và API không phản hồi.
1. Mô hình triển khai
Ví dụ chúng ta có hai server:
| Thành phần | Server nguồn | Server đích |
|---|---|---|
| IP | SERVER_SOURCE_IP | 14.225.18.11 |
| SSH | Port 65333 | Port 65333 |
| Qdrant | Docker | Docker |
| REST API | 6333 | 6333 |
| gRPC | 6334 | 6334 |
| Storage | /data/qdrant/data.lienvu.com | /data/storage/qdrant/data.fchat.ai |
| Container | qdrant | qdrant_app |
Trong ví dụ này, server nguồn chứa 1.414 collections và server đích cần được khởi tạo để phục vụ hệ thống AI.
Mục tiêu:
Di chuyển dữ liệu Qdrant sang server mới.
Giữ nguyên cấu trúc collections và vector.
Hạn chế thời gian gián đoạn dịch vụ.
Bảo vệ API bằng token.
Tự động khởi động Qdrant sau khi reboot.
Kiểm tra dữ liệu trước khi chuyển ứng dụng sang server mới.
2. Kiểm tra Qdrant trên server nguồn
Trước tiên, SSH vào server nguồn và kiểm tra container:
docker ps -a | grep qdrantKiểm tra thư mục lưu dữ liệu:
docker inspect qdrant \
--format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{println}}{{end}}'Ví dụ kết quả:
/data/qdrant/data.fchat.ai -> /qdrant/storageKiểm tra phiên bản Qdrant:
docker exec qdrant /qdrant/qdrant --versionNếu lệnh không phù hợp với image hiện tại, có thể kiểm tra qua API:
curl -H "api-key: $QDRANT_API_KEY" \
http://127.0.0.1:6333/Kiểm tra số collections
Nếu Qdrant đã cấu hình API Key, cần lấy key trước khi gọi API.
export QDRANT_API_KEY="$(docker inspect qdrant \
--format '{{range .Config.Env}}{{println .}}{{end}}' \
| sed -n 's/^QDRANT__SERVICE__API_KEY=//p' \
| head -n 1)"Không in API Key ra terminal hoặc đưa vào log công khai.
Sau đó kiểm tra:
curl -fsS \
-H "api-key: $QDRANT_API_KEY" \
http://127.0.0.1:6333/collections \
| python3 -c '
import json,sys
data=json.load(sys.stdin)
print("Total collections:",len(data["result"]["collections"]))
'Ví dụ:
Total collections: 1414Con số này sẽ được sử dụng để đối chiếu sau khi chuyển dữ liệu.
3. Chuẩn bị server mới
Trên server đích, kiểm tra Docker:
docker --version
docker infoNếu chưa cài Docker, có thể cài bằng repository chính thức phù hợp với hệ điều hành.
Ví dụ với AlmaLinux/RHEL:
dnf install -y dnf-plugins-core
dnf config-manager --add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io
systemctl enable --now dockerTạo thư mục lưu dữ liệu:
mkdir -p /data/storage/qdrant/data.fchat.aiKiểm tra dung lượng ổ đĩa:
df -h /data/storage/qdrantKiểm tra CPU và RAM:
nproc
free -hVới hệ thống có nhiều collections, nên chuẩn bị đủ RAM, dung lượng SSD và giới hạn file descriptor phù hợp.
4. Chuyển dữ liệu Qdrant bằng rsync
Qdrant sử dụng RocksDB để lưu dữ liệu. Không nên copy trực tiếp dữ liệu đang bị ghi liên tục vì có thể tạo ra bản sao không nhất quán.
Có hai phương án:
Phương án A: Dừng ghi và đồng bộ storage bằng rsync
Phù hợp khi có thể tạm dừng hệ thống để chuyển server.
Phương án B: Sử dụng Qdrant Snapshot API
Phù hợp khi muốn tạo bản sao nhất quán trong lúc hệ thống vẫn hoạt động. Cần lưu ý snapshot có thời điểm chụp cố định; những thay đổi phát sinh sau đó phải được đồng bộ bổ sung hoặc tạm dừng ghi khi cutover.
Trong bài viết này, chúng ta sử dụng phương án A.
Bước 1: Dừng ghi vào Qdrant nguồn
Tạm dừng các ứng dụng, worker, cronjob hoặc API đang ghi dữ liệu vào Qdrant.
Sau đó dừng container nguồn:
docker stop qdrantĐảm bảo dữ liệu đã được ghi xuống ổ đĩa trước khi đồng bộ.
Bước 2: Copy dữ liệu sang server đích
Chạy trên server nguồn:
rsync -avhP \
--timeout=600 \
-e "ssh -p 65333 \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=10" \
/data/qdrant/data.fchat.ai/ \
root@14.225.18.11:/data/storage/qdrant/data.fchat.ai/Giải thích:
-a: Giữ cấu trúc thư mục, quyền và thời gian sửa đổi.-v: Hiển thị thông tin.-h: Hiển thị dung lượng dễ đọc.-P: Hiển thị tiến độ và hỗ trợ tiếp tục file truyền dở.--timeout=600: Tránh chờ vô hạn khi kết nối bị treo.-e ssh: Sử dụng SSH để truyền dữ liệu an toàn.
Lưu ý dấu / cuối đường dẫn nguồn. Nó có nghĩa là copy nội dung bên trong thư mục.
Nếu quá trình bị ngắt, có thể chạy lại lệnh rsync.
Bước 3: Kiểm tra dữ liệu sau khi chuyển
Trên server đích:
du -sh /data/storage/qdrant/data.lienvu.com
find /data/storage/qdrant/data.lienvu.com/collections \
-mindepth 1 -maxdepth 1 -type d | wc -lSố thư mục collection có thể khác số collections được API công nhận, vì vậy không nên chỉ dựa vào số thư mục để kết luận dữ liệu đã đầy đủ.
Để đối chiếu lần cuối, khi Qdrant nguồn đã dừng và dữ liệu không còn thay đổi, có thể chạy rsync ở chế độ kiểm tra:
rsync -avhn --delete \
-e "ssh -p 65333" \
/data/qdrant/data.lienvu.com/ \
root@14.225.18.11:/data/storage/qdrant/data.lienvu.com/Tham số -n chỉ mô phỏng, không thay đổi dữ liệu.
Không dùng --delete trong lệnh đồng bộ thật nếu chưa chắc chắn server nguồn là bản dữ liệu chuẩn duy nhất.
5. Khởi tạo Qdrant Docker trên server mới
Để bảo mật, chỉ mở REST API và gRPC trên localhost.
Trên server đích, tạo thư mục cấu hình:
mkdir -p /etc/qdrant
chmod 700 /etc/qdrantTạo API Key mới
Sử dụng OpenSSL:
openssl rand -hex 32Lệnh này tạo token ngẫu nhiên có độ dài 64 ký tự hexadecimal.
Lưu token vào file cấu hình riêng:
read -rsp "Nhap Qdrant API Key: " QDRANT_API_KEY
echo
printf 'QDRANT__SERVICE__API_KEY=%s\n' "$QDRANT_API_KEY" \
> /etc/qdrant/qdrant.env
chmod 600 /etc/qdrant/qdrant.env
unset QDRANT_API_KEYKhông lưu token trong Git hoặc đưa trực tiếp vào source code.
Khởi tạo container
Ví dụ sử dụng Qdrant 1.14.1, là phiên bản được dùng trong quá trình chuyển thực tế:
docker run -d \
--name qdrant_app \
--restart unless-stopped \
--cpuset-cpus="0-7" \
--ulimit nofile=1048576:1048576 \
--env-file /etc/qdrant/qdrant.env \
-p 127.0.0.1:6333:6333 \
-p 127.0.0.1:6334:6334 \
-v /data/storage/qdrant/data.lienvu.com:/qdrant/storage:Z \
qdrant/qdrant:v1.14.1Giải thích cấu hình:
| Tham số | Công dụng |
|---|---|
--restart unless-stopped | Tự khởi động sau reboot |
--cpuset-cpus="0-7" | Giới hạn CPU affinity về 8 CPU |
--ulimit nofile=1048576:1048576 | Tăng giới hạn file descriptors |
--env-file | Nạp API Key từ file |
-p 127.0.0.1:6333:6333 | Chỉ mở REST API nội bộ |
-p 127.0.0.1:6334:6334 | Chỉ mở gRPC nội bộ |
:Z | Thiết lập SELinux label phù hợp cho bind mount trên hệ thống có SELinux |
Nếu image Qdrant nguồn sử dụng phiên bản khác, cần xác minh tính tương thích trước khi chuyển. Không nên đồng thời nâng cấp phiên bản và chuyển dữ liệu khi chưa có bản sao lưu.
6. Xử lý lỗi Too many open files
Trong quá trình khôi phục nhiều collections, Qdrant có thể gặp lỗi:
Too many open filesNguyên nhân thường là giới hạn file descriptors quá thấp so với số file RocksDB cần mở.
Kiểm tra:
docker exec qdrant_app sh -c \
'cat /proc/1/limits | grep "Max open files"'Cấu hình đề xuất để thử nghiệm:
--ulimit nofile=1048576:1048576Kết quả:
Max open files 1048576 1048576 filesNếu container đã tạo, việc thay đổi ulimit thường cần tạo lại container với cấu hình mới. Trước khi thực hiện, phải lưu đầy đủ cấu hình Docker hiện tại.
7. Xử lý lỗi Resource temporarily unavailable
Một lỗi khác có thể gặp khi khôi phục số lượng lớn collections:
terminate called after throwing an instance of 'std::system_error'
what(): Resource temporarily unavailable
Aborted (core dumped)Lỗi này có thể xuất hiện khi hệ thống không tạo được thêm thread hoặc không cấp phát được tài nguyên cần thiết.
Kiểm tra:
docker inspect qdrant_app \
--format 'Status={{.State.Status}} RestartCount={{.RestartCount}}'Kiểm tra tài nguyên:
docker stats --no-stream qdrant_app
free -hKiểm tra giới hạn PID:
docker exec qdrant_app sh -c '
cat /sys/fs/cgroup/pids.max
cat /sys/fs/cgroup/pids.current
cat /sys/fs/cgroup/pids.events
'Kiểm tra giới hạn Docker:
systemctl show docker.service \
-p TasksMax \
-p LimitNPROC \
-p LimitNOFILEGiới hạn CPU để giảm mức song song
Trong trường hợp server có 88 CPU và Qdrant phải khôi phục hơn 1.400 collections, có thể thử giảm CPU affinity:
docker update --cpuset-cpus="0-7" qdrant_appKiểm tra:
docker exec qdrant_app nprocKết quả dự kiến:
8Đây là biện pháp thử nghiệm để giảm mức song song, không phải giải pháp bảo đảm cho mọi lỗi tạo thread.
Sau khi khôi phục ổn định, có thể tăng dần CPU:
docker update --cpuset-cpus="0-15" qdrant_appKhông nên restart liên tục khi Qdrant đang khôi phục dữ liệu bình thường.
8. Kiểm tra Qdrant đã khởi động thành công
Theo dõi log:
docker logs -f --tail 50 qdrant_appKhi thành công, có thể xuất hiện:
Qdrant HTTP listening on 6333
Qdrant gRPC listening on 6334Kiểm tra API Key:
export QDRANT_API_KEY="$(
sed -n 's/^QDRANT__SERVICE__API_KEY=//p' \
/etc/qdrant/qdrant.env
)"Kiểm tra readiness:
curl -fsS \
-H "api-key: $QDRANT_API_KEY" \
http://127.0.0.1:6333/readyzKết quả thành công:
all shards are readyKiểm tra collections:
curl -fsS \
-H "api-key: $QDRANT_API_KEY" \
http://127.0.0.1:6333/collections \
| python3 -c '
import json,sys
d=json.load(sys.stdin)
print("Collections:",len(d["result"]["collections"]))
'Trong lần triển khai thực tế, server mới đã khởi động thành công với 1.413 collections và API trả về HTTP 200.
Lưu ý: Readiness thành công không tự động chứng minh mọi point đều đã được chuyển đầy đủ. Nếu yêu cầu khôi phục chính xác, cần đối chiếu danh sách collections, số point và dữ liệu quan trọng.
9. Hướng dẫn thay đổi mật khẩu / API Key Qdrant
Qdrant không sử dụng mật khẩu tài khoản theo cách thông thường. Trong cấu hình này, chúng ta dùng API Key để xác thực các request.
Để thay đổi API Key, cần cập nhật đồng bộ cả Qdrant và các ứng dụng đang kết nối.
Bước 1: Tạo token mới
openssl rand -hex 32Bước 2: Cập nhật file cấu hình
read -rsp "Nhap API Key moi: " NEW_QDRANT_KEY
echo
printf 'QDRANT__SERVICE__API_KEY=%s\n' "$NEW_QDRANT_KEY" \
> /etc/qdrant/qdrant.env
chmod 600 /etc/qdrant/qdrant.env
unset NEW_QDRANT_KEYBước 3: Tạo lại container với cấu hình mới
Quan trọng: docker restart không tự nạp lại nội dung --env-file đã thay đổi. Cần tạo lại container để áp dụng API Key mới.
Trước khi thực hiện, đảm bảo đã ghi lại cấu hình container, đường dẫn mount, CPU, ports và phiên bản image.
docker inspect qdrant_app > /root/qdrant-container-backup.jsonDừng và xóa container cũ:
docker stop qdrant_app
docker rm qdrant_appSau đó chạy lại lệnh docker run ở mục 5 với file qdrant.env mới.
Việc xóa container không xóa dữ liệu trong bind mount, nhưng cần tuyệt đối tránh xóa thư mục storage hoặc dùng lệnh xóa volume khi chưa xác minh.
Bước 4: Kiểm tra token mới
export QDRANT_API_KEY="$(
sed -n 's/^QDRANT__SERVICE__API_KEY=//p' \
/etc/qdrant/qdrant.env
)"
curl -fsS \
-H "api-key: $QDRANT_API_KEY" \
http://127.0.0.1:6333/collectionsNếu thành công, API trả về JSON chứa danh sách collections.
Nếu token không hợp lệ:
HTTP 401
Must provide an API key or an Authorization bearer tokenBước 5: Cập nhật ứng dụng
Ví dụ cấu hình môi trường Node.js:
QDRANT_URL=http://127.0.0.1:6333
QDRANT_API_KEY=YOUR_NEW_API_KEYVới ứng dụng chạy trên server khác, cần sử dụng kết nối riêng an toàn như VPN hoặc reverse proxy HTTPS có xác thực.
Sau khi đổi key, cập nhật tất cả dịch vụ sử dụng Qdrant, sau đó kiểm tra lại các chức năng AI, chatbot và tìm kiếm vector.
Lưu ý: Thay đổi API Key theo cách này gây gián đoạn ngắn và vô hiệu hóa key cũ. Nên thực hiện trong cửa sổ bảo trì hoặc có phương án chuyển đổi phù hợp.
10. Truy cập Qdrant Dashboard từ máy tính
Nếu Docker chỉ bind cổng 6333 vào localhost, không thể truy cập trực tiếp bằng IP public.
Cách an toàn nhất là SSH Tunnel.
Trên máy tính cá nhân:
ssh -p 65333 \
-L 6333:127.0.0.1:6333 \
root@14.225.18.11Sau đó mở trình duyệt:
http://localhost:6333/dashboardGiữ kết nối SSH trong khi sử dụng Dashboard.
Nếu muốn truy cập qua tên miền, có thể cấu hình Nginx reverse proxy với HTTPS, đồng thời giới hạn IP hoặc bổ sung xác thực.
Không nên công khai trực tiếp cổng 6333 và 6334 ra Internet.
11. Cập nhật dữ liệu sau khi chuyển server
Trong một số hệ thống, ứng dụng có thể tiếp tục ghi vào server Qdrant cũ trong thời gian chuyển đổi.
Khi đó, dữ liệu giữa hai server có thể khác nhau.
Ví dụ:
Server nguồn: 1.414 collections.
Server đích: 1.413 collections.
Điều này cho biết số collections khác nhau, nhưng không phản ánh toàn bộ chênh lệch point.
Một collection cũ vẫn có thể nhận thêm nhiều vector mà số lượng collections không thay đổi.
Không nên dùng rsync để ghi đè thư mục RocksDB của Qdrant đang hoạt động.
Các phương án phù hợp gồm:
Dừng ghi, dừng container và đồng bộ lại storage từ nguồn chuẩn.
Sử dụng Qdrant Snapshot API để sao lưu và phục hồi collection.
Đồng bộ dữ liệu ở cấp ứng dụng hoặc point ID nếu hai server đều đã nhận cập nhật.
Nếu chỉ một server nhận ghi, có thể thực hiện cutover có kiểm soát để tránh xung đột.
12. Các lệnh quản trị Qdrant thường dùng
Xem container:
docker ps -a | grep qdrantXem log:
docker logs --tail 100 qdrant_appTheo dõi tài nguyên:
docker stats qdrant_appKiểm tra tự khởi động:
docker inspect qdrant_app \
--format '{{.HostConfig.RestartPolicy.Name}}'Kiểm tra mount:
docker inspect qdrant_app \
--format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{println}}{{end}}'Kiểm tra CPU affinity:
docker inspect qdrant_app \
--format '{{.HostConfig.CpusetCpus}}'Kiểm tra giới hạn file:
docker exec qdrant_app sh -c \
'cat /proc/1/limits | grep "Max open files"'Kiểm tra trạng thái API:
curl -sS -o /dev/null \
-w "HTTP %{http_code}\n" \
-H "api-key: $QDRANT_API_KEY" \
http://127.0.0.1:6333/collections13. Checklist trước khi đưa Qdrant vào production
Đã sao lưu dữ liệu nguồn.
Đã kiểm tra phiên bản Qdrant tương thích.
Đã xác định đúng thư mục storage.
Đã đồng bộ dữ liệu từ trạng thái nhất quán.
Đã thiết lập giới hạn file descriptors phù hợp.
Đã cấu hình API Key đủ mạnh.
Đã giới hạn truy cập mạng.
Container tự khởi động sau reboot.
/readyztrả về trạng thái sẵn sàng.API
/collectionshoạt động.Đã kiểm tra dữ liệu và point quan trọng.
Đã cập nhật cấu hình các ứng dụng sử dụng Qdrant.
Đã thử nghiệm chức năng AI thực tế.
Chưa xóa dữ liệu server cũ trước khi xác minh hoàn tất.
Kết luận
Chuyển Qdrant sang server mới bằng Docker và rsync là phương án phù hợp khi cần di chuyển một hệ thống Vector Database có nhiều collections, đặc biệt khi có thể tạm dừng ghi trong thời gian chuyển đổi.
Ba vấn đề cần quan tâm nhất là:
Tính toàn vẹn dữ liệu: Không copy nóng RocksDB bằng rsync khi dữ liệu đang thay đổi.
Tài nguyên hệ thống: Cấu hình file descriptors, CPU và giới hạn tiến trình phù hợp khi khôi phục hàng nghìn collections.
Bảo mật: Sử dụng API Key mạnh, quản lý token ngoài source code và không mở Qdrant trực tiếp ra Internet.
Với hệ thống AI sử dụng Qdrant làm Vector Database, một quy trình chuyển đổi được kiểm soát sẽ giúp giảm rủi ro mất dữ liệu, hạn chế downtime và duy trì hoạt động ổn định sau khi chuyển server.



Nhận xét
Đăng nhận xét