Back to articles
Technology Insight

Xây dựng hạ tầng Serverless Vector Database siêu nhẹ trên VPS với USearch và SQLite: Tối ưu chi phí RAG cực hạn cho Micro-SaaS

May 26, 2026

Giới thiệu: Bài toán chi phí RAG của các Micro-SaaS

Trong kỷ nguyên trí tuệ nhân tạo, tính năng RAG (Retrieval-Augmented Generation) đã trở thành tiêu chuẩn vàng để nâng cao năng lực cho các ứng dụng LLM. Tuy nhiên, đối với các nhà phát triển Micro-SaaS hoặc các dự án Indie Hacker với ngân sách giới hạn, việc duy trì một hạ tầng Vector Database chuyên dụng là một gánh nặng tài chính không hề nhỏ. Các dịch vụ Cloud-native Vector Database nổi tiếng như Pinecone, Milvus Cloud, hay Qdrant Cloud thường có mức chi phí duy trì hàng tháng vượt quá ngân sách ban đầu của một dự án khởi nghiệp tinh gọn.

Liệu có giải pháp nào vừa đảm bảo tốc độ truy vấn mili-giây, vừa có thể chạy mượt mà trên một cấu hình VPS (Virtual Private Server) giá rẻ chỉ từ 5$ mỗi tháng? Câu trả lời nằm ở kiến trúc Serverless Vector Database tự chế, kết hợp giữa SQLite (để lưu trữ dữ liệu quan hệ và metadata) và USearch (thư viện tìm kiếm vector siêu nhẹ từ Unum). Bài viết này sẽ hướng dẫn bạn từng bước thiết kế và triển khai hệ thống này một cách tối ưu nhất.

Tại sao lại chọn SQLite và USearch cho kiến trúc siêu nhẹ?

Để hiểu tại sao sự kết hợp này lại mang tính cách mạng cho các ứng dụng nhỏ, chúng ta cần phân tích sâu vào đặc tính kỹ thuật của từng thành phần:

  • SQLite (Đơn giản, Nhẹ nhàng, Đáng tin cậy): Là một cơ sở dữ liệu dạng file (file-based), SQLite không cần chạy dưới dạng một tiến trình (process) nền riêng biệt. Nó chia sẻ chung bộ nhớ với ứng dụng chính, giúp giảm thiểu overhead và tiêu thụ RAM gần như bằng không khi không có truy vấn. Điều này hiện thực hóa khái niệm "Serverless" ngay trên một máy chủ truyền thống.
  • USearch (Được thiết kế cho phần cứng giới hạn): Khác với FAISS của Meta (vốn nặng nề và phức tạp) hay các giải pháp HNSW tích hợp sẵn trong PGVector đòi hỏi lượng RAM lớn, USearch là một công cụ định tuyến vector (Vector Search Engine) viết bằng C++11 nhưng cực kỳ nhỏ gọn. Nó cung cấp các binding hoàn hảo cho Python, JavaScript, và Go. USearch tập trung vào thuật toán HNSW nhưng được tối ưu hóa để sử dụng tài nguyên phần cứng một cách cực kỳ tiết kiệm, cho phép thực hiện hàng triệu phép tính khoảng cách với lượng tài nguyên tối thiểu.
Kiến trúc cốt lõi: Thay vì lưu trữ vector trực tiếp trong database quan hệ truyền thống khiến file cơ sở dữ liệu phình to và làm chậm các câu lệnh JOIN, chúng ta tách biệt: SQLite giữ vai trò lưu trữ Document Content và Metadata, trong khi USearch quản lý một file Index Vector (.usearch) riêng biệt trên đĩa cứng. Đọc và ghi dựa trên một ID duy nhất làm cầu nối.

Hướng dẫn triển khai chi tiết với Python

Dưới đây là hướng dẫn từng bước để xây dựng hệ thống tìm kiếm ngữ nghĩa siêu tiết kiệm bằng Python. Chúng ta sẽ sử dụng thư viện sentence-transformers để tạo embedding, sqlite3 (có sẵn trong Python) và usearch.

Bước 1: Cài đặt các thư viện cần thiết

Trước tiên, hãy SSH vào VPS của bạn và tiến hành cài đặt các package cần thiết qua pip:pip install usearch sentence-transformers rows

Bước 2: Khởi tạo cơ sở dữ liệu SQLite và USearch Index

Chúng ta sẽ viết một đoạn mã script để khởi tạo file database SQLite và cấu hình không gian vector cho USearch. Giả sử chúng ta sử dụng mô hình embedding all-MiniLM-L6-v2 sinh ra vector có 384 chiều (dimensions).

import sqlite3
from usearch.index import Index

# 1. Khởi tạo SQLite
conn = sqlite3.connect('microsaas_rag.db')
cursor = conn.cursor()
cursor.execute('''
    CREATE TABLE IF NOT EXISTS documents (
        id INTEGER PRIMARY KEY,
        content TEXT,
        metadata TEXT
    )
''')
conn.commit()

# 2. Khởi tạo USearch Index
# Sử dụng metric 'cos' (Cosine Similarity) hoặc 'l2sq' (Euclidean)
index = Index(ndim=384, metric='cos')
index.save('vectors.usearch')
print("Khởi tạo hạ tầng hoàn tất!")

Bước 3: Hàm thêm dữ liệu (Index Pipeline)

Mỗi khi có một tài liệu mới được tải lên hệ thống Micro-SaaS của bạn, quy trình sau sẽ được kích hoạt để đồng bộ hóa cả SQLite lẫn USearch:

from sentence_transformers import SentenceTransformer
import json

model = SentenceTransformer('all-MiniLM-L6-v2')

def insert_document(content, metadata_dict):
    # Bước 1: Tạo Embedding từ content
    vector = model.encode(content)
    
    # Bước 2: Lưu content và metadata vào SQLite để lấy ID tự tăng
    cursor.execute(
        "INSERT INTO documents (content, metadata) VALUES (?, ?)",
        (content, json.dumps(metadata_dict))
    )
    doc_id = cursor.lastrowid
    conn.commit()
    
    # Bước 3: Nạp Vector vào USearch Index với ID tương ứng
    index.append(doc_id, vector)
    index.save('vectors.usearch')
    print(f"Đã index tài liệu ID: {doc_id}")

Bước 4: Quy trình truy vấn (Query Pipeline) cho RAG

Khi người dùng đặt câu hỏi, hệ thống sẽ chuyển câu hỏi thành vector, thực hiện tìm kiếm K-gần nhất (K-Nearest Neighbors) trên USearch để lấy ra các ID phù hợp, sau đó truy vấn SQLite để lấy nội dung text thô làm ngữ cảnh (Context) cho LLM.

def search_rag_context(query, top_k=3):
    # 1. Tạo vector cho câu hỏi của người dùng
    query_vector = model.encode(query)
    
    # 2. Tìm kiếm trên USearch
    matches = index.search(query_vector, top_k)
    
    # 3. Lấy danh sách ID kết quả
    matched_ids = [match.key for match in matches]
    
    if not matched_ids:
        return []
        
    # 4. Truy vấn thông tin chi tiết từ SQLite
    placeholders = ','.join('?' for _ in matched_ids)
    cursor.execute(f"SELECT id, content FROM documents WHERE id IN ({placeholders})", matched_ids)
    rows = cursor.fetchall()
    
    return rows

Chiến lược tối ưu hóa và vận hành trên VPS giá rẻ

Để hạ tầng này hoạt động ổn định ở môi trường Production với chi phí tối thiểu, bạn cần lưu ý các kỹ thuật tối ưu hóa nâng cao sau:

1. Quản lý bộ nhớ đệm (Memory Mapping)

USearch hỗ trợ cơ chế mmap (Memory-mapped files). Điều này có nghĩa là file index dữ liệu của bạn có thể lớn hơn dung lượng RAM vật lý của VPS rất nhiều. Hệ điều hành sẽ tự động nạp các phần của file index vào RAM khi cần thiết và giải phóng khi không dùng đến. Nhờ vậy, một VPS có 1GB RAM vẫn có thể tìm kiếm trên tập dữ liệu hàng triệu vector mà không sợ bị dính lỗi Out Of Memory (OOM).

2. Backup và Phục hồi (Disaster Recovery)

Vì toàn bộ cơ sở dữ liệu của bạn giờ đây chỉ gói gọn trong 2 tập tin duy nhất: microsaas_rag.db và vectors.usearch, việc sao lưu trở nên vô cùng đơn giản. Bạn chỉ cần thiết lập một cronjob định kỳ nén 2 file này lại và đẩy lên các dịch vụ lưu trữ giá rẻ như Cloudflare R2 hoặc AWS S3 Standard-IA. Chi phí lưu trữ gần như bằng 0$.

3. Đóng gói thành một Microservice Serverless độc lập

Để tích hợp vào hệ thống Micro-SaaS lớn hơn của bạn, hãy đóng gói đoạn code trên bằng FastAPI và chạy nó thông qua Docker. Bạn có thể giới hạn tài nguyên của container này một cách nghiêm ngặt để tránh ảnh hưởng đến các service khác chạy chung trên cùng một VPS:services: rag-vector-db: image: my-usrearch-sqlite-app:latest deploy: resources: limits: cpus: '0.50' memory: 512M

Kết luận

Tối ưu hóa chi phí vận hành mà vẫn duy trì được trải nghiệm người dùng xuất sắc chính là chìa khóa sống còn của các sản phẩm Micro-SaaS trong giai đoạn hiện tại. Bằng cách loại bỏ các giải pháp Vector Database đám mây đắt đỏ và thay thế bằng kiến trúc kết hợp giữa SQLite và USearch, bạn hoàn toàn có thể tự làm chủ một hệ thống RAG mạnh mẽ, mượt mà trực tiếp trên hạ tầng VPS giá rẻ.

Giải pháp này không chỉ giúp bạn tiết kiệm hàng trăm USD mỗi tháng mà còn giúp cấu trúc mã nguồn của bạn trở nên tinh gọn, dễ bảo trì và dễ dàng mở rộng quy mô khi ứng dụng của bạn đạt được cột mốc tăng trưởng mới.

Xây dựng hạ tầng Serverless Vector Database siêu nhẹ trên VPS với USearch và SQLite: Tối ưu chi phí RAG cực hạn cho Micro-SaaS | DPTCloud