Quay lại danh sách
Tin tức công nghệ

Tối ưu hóa VPS chạy 'Vector Search' quy mô lớn: Cấu hình phân tầng bộ nhớ (Memory-Mapped Files) với HNSW Index trong pgvector

25 tháng 5, 2026

Đặt vấn đề: Thách thức chi phí RAM khi Scale-up Vector Search

Trong kỷ nguyên của Trí tuệ nhân tạo (AI) và các mô hình ngôn ngữ lớn (LLM), Tìm kiếm ngữ nghĩa (Semantic Search) và Hệ thống khuyến nghị (Recommendation Systems) đã trở thành những tính năng cốt lõi của ứng dụng doanh nghiệp. Đứng sau các hệ thống này là công nghệ Vector Search (Tìm kiếm Vector), nơi các dữ liệu phi cấu trúc như văn bản, hình ảnh được chuyển đổi thành các chuỗi số đa chiều (embeddings).

Khi triển khai trên PostgreSQL sử dụng tiện ích mở rộng pgvector, thuật toán chỉ mục HNSW (Hierarchical Navigable Small World) thường được lựa chọn nhờ tốc độ truy vấn vượt trội và độ chính xác cao. Tuy nhiên, HNSW có một nhược điểm chí mạng: Nó cực kỳ ngốn RAM. Theo nguyên lý hoạt động mặc định, toàn bộ cấu trúc đồ thị của HNSW Index phải được tải và lưu trú hoàn toàn trên bộ nhớ RAM để đảm bảo tốc độ tìm kiếm lân cận gần nhất (Nearest Neighbor Search) đạt hiệu năng mili-giây.

Đối với các doanh nghiệp vận hành trên hạ tầng đám mây hoặc máy chủ ảo (VPS), việc nâng cấp RAM (Scale-up) tuyến tính theo sự tăng trưởng của dữ liệu là một bài toán kinh tế nan giải. Chi phí thuê VPS có dung lượng RAM lớn (ví dụ: 128GB hoặc 256GB RAM) tăng trưởng theo cấp số nhân, có thể nuốt chửng biên lợi nhuận của các startup và doanh nghiệp tầm trung. Câu hỏi đặt ra là: Làm thế nào để mở rộng quy mô lưu trữ hàng triệu vector độ chiều cao trên một cấu hình VPS giới hạn mà không làm suy giảm nghiêm trọng tốc độ truy vấn?

Câu trả lời nằm ở cơ chế Phân tầng bộ nhớ (Memory-Tiering) thông qua việc tận dụng Memory-Mapped Files (mmap) của hệ điều hành Linux kết hợp với các kỹ thuật cấu hình chuyên sâu trong PostgreSQL.

Hiểu sâu về cấu trúc đồ thị HNSW và cơ chế mmap trong PostgreSQL

1. Tại sao HNSW Index lại tiêu tốn tài nguyên RAM?

Thuật toán HNSW xây dựng một cấu trúc đồ thị đa tầng, nơi các node là các vector dữ liệu và các cạnh biểu diễn mối quan hệ tương đồng giữa chúng. Khi thực hiện tìm kiếm, thuật toán sẽ "nhảy" qua các node trên đồ thị từ tầng cao xuống tầng thấp để tìm ra kết quả tối ưu nhất. Để đạt tốc độ này, mỗi truy vấn yêu cầu truy cập ngẫu nhiên (random access) vào các node với tần suất cực cao. Nếu cấu trúc đồ thị này bị đẩy xuống ổ đĩa truyền thống, độ trễ I/O sẽ khiến hệ thống bị nghẽn cổ chai ngay lập tức.

2. Cơ chế Memory-Mapped Files (mmap) hoạt động như thế nào?

Hệ điều hành Linux cung cấp cơ chế mmap, cho phép ánh xạ trực tiếp một file trên ổ cứng (ở đây là các tệp dữ liệu chỉ mục của PostgreSQL) vào không gian địa chỉ ảo của tiến trình. Thay vì đọc toàn bộ file vào RAM vật lý, kernel chỉ nạp các trang dữ liệu (pages) vào RAM khi ứng dụng thực sự cần truy cập đến chúng (gọi là cơ chế Demand Paging và kích hoạt Page Fault).

Bằng cách cấu hình tối ưu, chúng ta có thể biến ổ cứng NVMe tốc độ cao của VPS thành một tầng mở rộng của bộ nhớ (Virtual Memory Tier). Những phần đồ thị HNSW thường xuyên được truy cập (hot data) sẽ được giữ lại trên RAM vật lý nhờ cơ chế Page Cache của Linux, trong khi những phần ít sử dụng (cold data) sẽ nằm an toàn trên NVMe và chỉ được nạp lên khi có truy vấn đặc biệt.

Chiến lược cấu hình phân tầng bộ nhớ cho pgvector trên VPS

Để triển khai giải pháp này một cách hiệu quả trên môi trường production, chúng ta cần thực hiện đồng bộ từ việc tối ưu cấu trúc chỉ mục cho đến tinh chỉnh các tham số hệ thống của PostgreSQL và Linux OS.

Bước 1: Tối ưu hóa bộ tham số khi khởi tạo HNSW Index

Khi khởi tạo chỉ mục HNSW trong pgvector, bạn có thể kiểm soát kích thước tổng thể của đồ thị thông qua hai tham số quan trọng là m và ef_construction. Việc giảm nhẹ các tham số này sẽ làm giảm đáng kể dung lượng bộ nhớ yêu cầu mà không làm mất đi quá nhiều độ chính xác (Recall Rate).

CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops) 
WITH (m = 16, ef_construction = 64);
  • m (Default: 16): Số lượng liên kết tối đa của mỗi node trong đồ thị. Giảm m giúp đồ thị thanh thoát hơn, dung lượng file index nhỏ hơn đáng kể.
  • ef_construction (Default: 64): Kích thước danh sách động được sử dụng trong quá trình xây dựng index.

Bước 2: Cấu hình các tham số bộ nhớ trong PostgreSQL (postgresql.conf)

Chúng ta cần cấu hình để PostgreSQL hiểu rằng hệ thống đang vận hành trên một kiến trúc lưu trữ có độ trễ I/O thấp (NVMe SSD) và tận dụng tối đa cơ chế OS Cache thay vì nhồi nhét vào shared_buffers.

  1. shared_buffers: Thông thường, đối với cơ sở dữ liệu truyền thống, người ta khuyên cấu hình bằng 25% đến 40% tổng RAM hệ thống. Tuy nhiên, đối với kiến trúc dựa vào mmap để xử lý Vector dung lượng lớn, hãy giữ shared_buffers ở mức vừa phải (khoảng 20-25% RAM) để nhường lại phần lớn không gian RAM trống cho Linux Page Cache tự do quản lý file đồ thị HNSW.
  2. effective_cache_size: Hãy đặt giá trị này tương đương 75% đến 80% tổng RAM vật lý của VPS. Tham số này giúp bộ tối ưu hóa truy vấn (Query Planner) biết được dung lượng bộ nhớ thực tế có sẵn cho việc cache dữ liệu (bao gồm cả RAM của Postgres và OS Cache), từ đó ưu tiên quét chỉ mục HNSW qua mmap.
  3. random_page_cost: Mặc định tham số này là 4.0 (phù hợp cho ổ HDD cũ). Trên VPS hiện đại sử dụng ổ cứng NVMe chuyên dụng, hãy hạ giá trị này xuống 1.1 hoặc 1.0. Điều này thông báo cho PostgreSQL rằng chi phí truy cập ngẫu nhiên vào các trang dữ liệu trên ổ đĩa là rất rẻ, khuyến khích hệ thống thực hiện các phép toán duyệt đồ thị trực tiếp từ file ánh xạ.
Cấu hình gợi ý cho VPS 16GB RAM chạy Vector Search lớn:
shared_buffers = 4GB
effective_cache_size = 12GB
random_page_cost = 1.1

Tinh chỉnh hệ điều hành Linux để tối ưu hóa mmap hiệu năng cao

Nếu chỉ cấu hình ở tầng PostgreSQL, hệ thống vẫn có thể gặp hiện tượng nghẽn do cơ chế quản lý bộ nhớ ảo mặc định của Linux không được thiết kế cho các file index khổng lồ thay đổi liên tục. Hãy áp dụng các tinh chỉnh sau vào file /etc/sysctl.conf:

1. Điều chỉnh độ nhạy Swapping (vm.swappiness)

Mặc định, Linux sẽ chủ động đẩy các trang bộ nhớ ẩn danh ít dùng xuống phân vùng Swap để giải phóng Page Cache. Điều này có thể vô tình đẩy các tiến trình con của Postgres xuống ổ đĩa, gây sụt giảm hiệu năng đột ngột. Hãy hạ độ nhạy swap xuống mức tối thiểu:

sysctl -w vm.swappiness=1

2. Cấu hình giải phóng và ghi đệm bất đồng bộ (Dirty Pages)

Khi các vector mới được chèn vào (INSERT/UPDATE), chỉ mục HNSW sẽ cập nhật liên tục các trang dữ liệu trên bộ nhớ. Chúng ta cần cấu hình để kernel ghi các trang "bẩn" (dirty pages) này xuống ổ đĩa NVMe một cách mượt mà, tránh hiện tượng dồn ứ I/O (I/O spikes).

sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_ratio=10

Cấu hình này đảm bảo rằng khi lượng dữ liệu thay đổi trên RAM đạt đến 5%, Linux sẽ kích hoạt các tiến trình chạy ngầm để xả dữ liệu xuống ổ đĩa NVMe một cách tuần tự, giữ cho hệ thống luôn ổn định.

Đánh giá hiệu năng và Kết luận

Áp dụng mô hình phân tầng bộ nhớ với mmap và HNSW mang lại những lợi ích kinh tế và kỹ thuật vượt trội cho doanh nghiệp:

  • Tiết kiệm chi phí phần cứng: Khả năng vận hành các bộ dữ liệu vector quy mô lớn gấp 2 đến 3 lần dung lượng RAM vật lý của VPS mà không cần nâng cấp gói cấu hình máy chủ tốn kém.
  • Hiệu năng tiệm cận bộ nhớ gốc: Nhờ tốc độ đọc ghi vượt trội của ổ cứng NVMe thế hệ mới kết hợp với thuật toán tối ưu của Linux Page Cache, các truy vấn đối với dữ liệu "nóng" (hot data) vẫn đạt độ trễ cực thấp (dưới 10ms), trong khi các truy vấn diện rộng chỉ tăng độ trễ ở mức chấp nhận được.
  • Khả năng mở rộng bền vững: Giúp kiến trúc hệ thống dữ liệu của doanh nghiệp sẵn sàng cho việc tăng trưởng quy mô trong tương lai, chuyển dịch trọng tâm đầu tư tài nguyên từ RAM vật lý đắt đỏ sang ổ cứng lưu trữ NVMe có chi phí hợp lý hơn nhiều.

Tóm lại, tối ưu hóa Vector Search quy mô lớn không chỉ là câu chuyện mua thêm tài nguyên, mà là nghệ thuật làm chủ và cấu hình đồng bộ giữa phần mềm (pgvector, PostgreSQL) và phần cứng thông qua hệ điều hành. Chúc các bạn cấu hình thành công!

Tối ưu hóa VPS chạy 'Vector Search' quy mô lớn: Cấu hình phân tầng bộ nhớ (Memory-Mapped Files) với HNSW Index trong pgvector | DPTCloud