EzyVector lưu dữ liệu vector và HNSW index trên filesystem, nhưng hai phần này có vai trò khác nhau. Vector data là dữ liệu embedding thực tế của point, còn HNSW index là cấu trúc chỉ mục giúp tìm kiếm các vector gần nhau nhanh hơn.
Cách tách riêng này giúp EzyVector vừa có thể lưu trữ vector bền vững, vừa có thể tăng tốc tìm kiếm bằng index, đồng thời vẫn giữ MySQL làm nơi quản lý metadata và payload.

Vector Data Và HNSW Index Khác Nhau Như Thế Nào?

Một point trong EzyVector thường gồm ba phần:
  • id: định danh của point.
  • vector: embedding dùng cho tìm kiếm tương đồng.
  • payload: dữ liệu bổ sung để trả về cùng kết quả tìm kiếm.
Trong đó, metadata và payload được lưu ở MySQL. Còn vector và HNSW index được lưu trên filesystem.
flowchart TD
    A[Point] --> B[Metadata]
    A --> C[Payload]
    A --> D[Vector embedding]

    B --> E[(MySQL)]
    C --> E

    D --> F[Vector Storage trên filesystem]
    D --> G[HNSW Index trên filesystem]
Có thể hiểu ngắn gọn:
  • Vector storage là kho lưu vector.
  • HNSW index là bản đồ điều hướng để tìm vector gần nhau nhanh hơn.
Nếu không có HNSW index, hệ thống vẫn có thể tìm kiếm bằng cách quét vector storage. Nếu có HNSW index, hệ thống ưu tiên dùng index để giảm độ trễ tìm kiếm.

EzyVector Lưu Vector Data Như Thế Nào?

Khi ứng dụng upsert point vào một collection, EzyVector lưu metadata của point vào MySQL, sau đó ghi vector xuống file storage.
Vector được lưu theo slot. Mỗi slot tương ứng với một vị trí vật lý trong file, và có mapping tới point_id. Điều này giúp hệ thống đọc lại vector theo vị trí cố định mà không cần tải toàn bộ dữ liệu vào Java heap.
flowchart LR
    A[Upsert point] --> B[Lưu metadata vào MySQL]
    B --> C[Chuẩn hóa vector]
    C --> D[Ghi vector vào vector file]
    D --> E[Ghi point_id mapping]
    E --> F[Cập nhật HNSW nếu index đã sẵn sàng]
Vector storage có thể được dùng trong hai tình huống quan trọng:
  • Fallback search: khi HNSW index chưa sẵn sàng, EzyVector có thể scan vector trong file để tìm kết quả gần nhất.
  • Recovery/backfill: khi cần khôi phục hoặc đồng bộ lại dữ liệu vector, hệ thống có thể dựa vào dữ liệu trong MySQL để ghi lại vector storage.

Vì Sao Vector Được Chuẩn Hóa?

EzyVector hiện tập trung vào cosine similarity. Với cosine similarity, điều quan trọng là hướng của vector, không phải độ dài tuyệt đối của vector.
Vì vậy, trước khi lưu và tìm kiếm, vector được chuẩn hóa. Khi đó phép tính similarity có thể được thực hiện hiệu quả hơn bằng tích vô hướng giữa các vector đã chuẩn hóa.
Điều này giúp score phản ánh mức độ tương đồng giữa query vector và vector đã lưu.

HNSW Index Được Lưu Như Thế Nào?

HNSW, viết tắt của Hierarchical Navigable Small World, là cấu trúc chỉ mục phục vụ approximate nearest neighbor search. Thay vì so sánh query với toàn bộ vector trong collection, HNSW tổ chức các vector thành một đồ thị nhiều tầng.
Mỗi node trong HNSW đại diện cho một point. Node có vector đã chuẩn hóa, level và danh sách neighbor ở từng tầng. Khi tìm kiếm, hệ thống bắt đầu từ một entry point, đi qua các neighbor gần hơn, rồi thu hẹp dần về nhóm kết quả tốt nhất.
flowchart TD
    A[HNSW Index] --> B[Entry point]
    A --> C[Node]
    C --> D[Vector đã chuẩn hóa]
    C --> E[Level]
    C --> F[Neighbors theo từng tầng]

    B --> G[Tìm kiếm từ tầng cao xuống tầng thấp]
    G --> H[Trả về top K vector gần nhất]
Sau khi HNSW index được build xong, EzyVector lưu index xuống file. Nhờ vậy, khi server khởi động lại, hệ thống có thể load lại index từ filesystem thay vì phải build lại từ đầu.

Khi Nào EzyVector Build HNSW Index?

EzyVector có thể khởi động quá trình build HNSW index khi collection được tạo, khi có dữ liệu mới được upsert, hoặc khi có request search nhưng index chưa sẵn sàng.
Quá trình build chạy ở nền. Hệ thống đọc point theo từng lô, insert vector vào HNSW index, sau đó lưu index xuống file khi hoàn tất.
sequenceDiagram
    participant Service as Vector Service
    participant DB as MySQL
    participant Index as HNSW Index
    participant File as Filesystem

    Service->>DB: Đọc point theo từng lô
    DB-->>Service: Trả về vector và point metadata
    Service->>Index: Insert vector vào HNSW
    Index->>File: Lưu HNSW index
    Service->>Service: Đánh dấu index sẵn sàng
Trong thời gian index đang build, EzyVector không cần dừng search. Nếu HNSW chưa sẵn sàng, hệ thống fallback sang tìm kiếm tuần tự trên vector storage.

Điều Gì Xảy Ra Khi Có Point Mới?

Khi một point mới được thêm hoặc point cũ được cập nhật, EzyVector thực hiện đồng thời hai việc:
  • ghi vector mới xuống vector storage,
  • cập nhật HNSW index nếu index đã được load và sẵn sàng.
Nếu HNSW index đã sẵn sàng, dữ liệu mới sẽ được insert vào index và index được lưu lại. Nếu HNSW chưa sẵn sàng, dữ liệu vẫn được lưu vào MySQL và vector storage trước; index có thể được build hoặc rebuild ở nền sau đó.
Cách này giúp thao tác ghi không phụ thuộc hoàn toàn vào trạng thái của index.

Vì Sao Không Chỉ Lưu HNSW Index?

HNSW index rất hữu ích cho tìm kiếm nhanh, nhưng nó không nên là nơi duy nhất lưu vector.
Lý do là HNSW index là cấu trúc phục vụ truy vấn, không phải toàn bộ mô hình dữ liệu của hệ thống. EzyVector vẫn cần vector storage riêng để:
  • fallback search khi index chưa sẵn sàng,
  • rebuild index khi cần,
  • kiểm tra dữ liệu vector theo slot,
  • tách dữ liệu gốc khỏi cấu trúc chỉ mục,
  • giảm rủi ro khi file index bị lỗi hoặc không khớp cấu hình.
Nói cách khác, vector storage là lớp dữ liệu nền, còn HNSW index là lớp tăng tốc truy vấn.

Vì Sao Không Chỉ Lưu Vector Trong MySQL?

MySQL vẫn lưu dữ liệu point và có thể giữ vector như một nguồn dữ liệu có cấu trúc, nhưng tìm kiếm vector trực tiếp từ MySQL không phải hướng tối ưu khi collection lớn.
Vector embedding thường có kích thước cao. Nếu mỗi lần search đều đọc nhiều vector từ MySQL, hệ thống sẽ gặp áp lực lớn về I/O, network, CPU và độ trễ truy vấn.
Filesystem phù hợp hơn cho việc lưu vector dạng tuần tự, đọc theo chunk và memory-map khi cần scan. HNSW index lại phù hợp hơn cho truy vấn gần đúng tốc độ cao.
Vì vậy, EzyVector chọn cách kết hợp:
  • MySQL cho metadata, payload và quản trị.
  • Vector storage cho dữ liệu embedding.
  • HNSW index cho tìm kiếm nhanh.

Luồng Tìm Kiếm Tổng Quát

Khi nhận request search, EzyVector kiểm tra collection, khởi động backfill hoặc build index nếu cần, rồi chọn cách tìm kiếm phù hợp.
flowchart TD
    A[Search request] --> B[Kiểm tra collection]
    B --> C[Đảm bảo dữ liệu vector đang được backfill nếu cần]
    C --> D[Đảm bảo HNSW đang được build nếu cần]
    D --> E{HNSW sẵn sàng?}

    E -->|Có| F[Tìm bằng HNSW index]
    E -->|Không| G[Scan vector storage]

    F --> H[Lấy payload từ MySQL]
    G --> H
    H --> I[Trả về id, score, payload]
Nhờ cơ chế này, EzyVector có thể ưu tiên hiệu năng khi index đã sẵn sàng, nhưng vẫn giữ khả năng hoạt động khi index chưa hoàn tất.

Kết Luận

EzyVector lưu hai loại dữ liệu trên filesystem:
  • Vector data: dữ liệu embedding đã chuẩn hóa, dùng làm lớp lưu trữ vector vật lý.
  • HNSW index: cấu trúc chỉ mục ANN, dùng để tìm kiếm vector gần nhau nhanh hơn.
Hai phần này bổ sung cho nhau. Vector storage giúp hệ thống có nền dữ liệu ổn định để scan, backfill và rebuild. HNSW index giúp tăng tốc truy vấn khi collection lớn. MySQL vẫn giữ metadata và payload để hệ thống dễ quản trị, dễ backup và dễ tích hợp với EzyPlatform.
Cách thiết kế này giúp EzyVector cân bằng giữa độ đơn giản, khả năng vận hành và hiệu năng tìm kiếm vector.