當向量資料集規模超過可用記憶體時,HNSW、IVF_FLAT 等記憶體索引受記憶體容量限制,難以同時滿足效能與成本要求。DiskANN 將索引資料下沉至磁碟,在資料規模超出記憶體容量的情況下仍可提供較高的搜尋精度與查詢效能,適用於數十億級及以上規模的向量檢索情境。
限制說明
項 | 說明 |
索引啟用方式 | 计算节点的CU 类型為容量型的叢集預設啟用 DiskANN;其他執行個體可在建立索引時顯式指定索引類型為 |
部署模式版本要求 | 磁碟模式要求阿里雲 Milvus 叢集版本為 2.6.18 及以上;2.6.3 版本僅支援效能模式。 |
工作原理
DiskANN 結合 Vamana 圖與 RaBitQ 量化兩項技術實現磁碟上的高效向量搜尋。
Vamana 圖
Vamana 圖是 DiskANN 基於磁碟策略的核心結構。與 HNSW 的多層結構不同,Vamana 採用單層稀疏圖,通過兩輪剪枝構圖,在保持圖連通性的同時引入更多長程邊,減少搜尋收斂所需的跳數。
構建過程如下:
初始隨機串連:每個向量作為圖中一個節點,節點之間初始隨機串連形成密集網路,通常每個節點初始約 500 條邊,以保證連通性。
兩輪剪枝最佳化:剪除多餘邊,根據節點距離剔除低品質串連,優先保留高品質邊,每個節點的最大邊數由
MaxDegree限制;引入長程邊,串連向量空間中相距較遠的資料點形成跳轉捷徑,加快圖上導航速度,構圖時鄰接搜尋的廣度由SearchListSize決定。
開源 DiskANN 將每個節點的鄰居列表與其全精度向量存放在同一磁碟扇區,搜尋時通過一次磁碟讀取同時獲得鄰居關係與原始向量,實現隱式重排,但整個搜尋過程涉及大量串列磁碟 I/O。阿里雲 Milvus 將 Vamana 圖索引在記憶體中重新組織,使搜尋過程不產生磁碟 I/O,僅在最後的 Rerank 階段從磁碟讀取原始向量。
RaBitQ 量化
RaBitQ(Random Bit Quantization)將向量歸一化後映射到超立方體的頂點上,每一維僅需 1 bit 表示,從而壓縮儲存開銷並加速向量間的近似距離計算。
高維空間中隨機向量之間的角度高度集中,量化到超立方體頂點的誤差以 O(1/√d) 的速率收斂,因此維度越高、量化誤差越小。在 768 維空間中,1 bit 量化的誤差已經很小。阿里雲 Milvus 在標準 1-bit RaBitQ 基礎上採用 4-bit 擴充模式,每一維使用 4 bit 編碼殘差資訊,以平衡壓縮比與精度。
啟用 DiskANN 索引
步驟一:建立容量型叢集
建立阿里雲 Milvus 執行個體時,將计算节点的CU 类型設定為容量型。叢集建立完成後無需額外配置,即預設使用 DiskANN RaBitQ 索引類型;建立 Collection 時若索引類型配置為 AUTOINDEX,系統自動匹配 DiskANN 作為底層索引實現。
建立執行個體的具體操作,請參見快速建立Milvus執行個體。
使用 AUTOINDEX 時,describe_index 返回的索引類型仍為 AUTOINDEX,不顯示自動匹配後的底層索引。如需確認實際生效的索引類型,可查詢 Segment 級資訊,index_name 為 DISKANN 即表示已匹配 DiskANN:
from pymilvus import connections, utility
connections.connect(uri="http://<endpoint>:19530", token="<user>:<password>")
for seg in utility.get_query_segment_info("<collection_name>"):
print(seg.segmentID, seg.num_rows, seg.index_name)步驟二:選擇部署模式
同一份 DiskANN RaBitQ 索引支援兩種部署模式,可根據業務訴求選擇載入與搜尋方式:
部署模式 | 載入行為 | 適用情境 |
效能模式(預設) | Vamana 圖與 RaBitQ 量化編碼均載入至記憶體 | 追求高 QPS 與低延遲的線上檢索情境 |
磁碟模式 | Vamana 圖存放在磁碟,僅 RaBitQ 編碼載入至記憶體 | 對成本敏感,可接受一定 QPS 下降與延遲增加的情境 |
若無明確的成本壓縮需求,建議保持預設的效能模式;記憶體成本是主要約束且業務可接受查詢效能下降時,再切換為磁碟模式。磁碟模式要求叢集版本為 2.6.18 及以上。
步驟三:規劃記憶體與機型
按以下公式計算理論最小記憶體。實際記憶體佔用略高於理論值,建議按理論值 × 1.5 預留資源。
效能模式:
記憶體大小 = 資料條數 × (維度 / 2 + 228) 位元組磁碟模式:
記憶體大小 = 資料條數 × (維度 / 2) 位元組以 1 億條 768 維向量為例:
部署模式 | 理論記憶體 | 推薦記憶體(× 1.5) | 推薦機型 |
效能模式 | 1 億 × (384 + 228) 位元組 ≈ 57 GB | 約 85 GB | 2 台 16C64G 計算節點 |
磁碟模式 | 1 億 × 384 位元組 ≈ 36 GB | 約 54 GB | 1 台 16C64G 計算節點 |
步驟四:切換部署模式(可選)
預設使用效能模式。切換部署模式無需重建索引,僅在 load 階段完成模式切換,流程為 release Collection、修改 Collection 屬性、重新 load。
切換過程中 Collection 會被 release 並重新 load,期間該 Collection 的查詢能力短暫不可用,建議在業務低峰期執行。
使用以下 Python 指令碼完成切換:
from pymilvus import MilvusClient
CLUSTER_ENDPOINT = "http://xxx-internal.milvus.aliyuncs.com:19530"
TOKEN = "<user>:<password>"
COLLECTION_NAME = "<collection_name>"
def set_diskann_mode(mode: str):
client = MilvusClient(uri=CLUSTER_ENDPOINT, token=TOKEN, timeout=7200)
# 1. release collection
client.release_collection(COLLECTION_NAME)
# 2. 修改部署模式
client.alter_collection_properties(
COLLECTION_NAME,
properties={"diskann.rabitq_mode": mode},
)
# 3. 重新 load
client.load_collection(COLLECTION_NAME, timeout=7200)
client.close()
if __name__ == '__main__':
set_diskann_mode("disk") # 切換到磁碟模式
# set_diskann_mode("perf") # 切回效能模式參數說明:
參數 | 說明 |
| Milvus 執行個體的訪問 Endpoint,可使用內網或公網地址,均需攜帶連接埠 19530。 |
| 訪問憑證,格式為 |
| 目標 Collection 名稱。 |
| 部署模式取值: |
切換完成後,可通過 describe_collection 返回的 properties 中的 diskann.rabitq_mode 確認當前模式。
參數配置
調整 DiskANN 參數可針對特定資料集與搜尋負載,在速度、準確性與記憶體開銷之間取得平衡。
當前引擎不會拒絕超出下述建議取值範圍的參數。填入超出範圍或不滿足推薦關係的值不會返回錯誤,但可能導致召回率或查詢效能異常,配置前需自行確認取值合理。
索引構建參數
以下參數影響索引的構建方式,調整會影響索引大小、構建時間與搜尋品質。
參數 | 說明 | 取值 | 調優建議 |
| 控制 Vamana 圖中每個資料點的最大串連(邊)數。 | 整數,建議 [1, 512],預設 | 值越大圖越密集,召回率越高,記憶體佔用與構建時間也隨之上升。多數情境建議設定在 [10, 100] 範圍內。 |
| 索引構建過程中為每個節點搜尋近鄰的候選池大小。為添加到圖中的每個節點維護包含 | 整數,建議不小於 | 值越大越有可能為每個節點找到真正的近鄰,圖品質與召回率越好,但索引構建時間顯著增加。取值小於 |
搜尋參數
以下參數影響搜尋行為,調整會影響搜尋速度、延遲與資源消耗。
參數 | 說明 | 取值 | 調優建議 |
| 搜尋過程中遍曆圖時維護的候選池大小。 | 整數,預設 | 值越大找到真正近鄰的幾率越高(召回率越高),搜尋延遲也會增加。建議設定為等於或略大於待檢索的結果數量 |
| 搜尋過程中是否使用原始向量進行精排。 | bool,預設 | 追求高 QPS 的情境可關閉精排,QPS 提升明顯但召回率有所下降,在高 |
| 搜尋過程提前終止閾值,連續 N 步無改善時停止搜尋。 | 整數,建議 (0, 200],預設 | 值越大搜尋越充分,召回率越高;值越小搜尋早停越早,QPS 提升但召回率下降。 |
上述搜尋參數需在資料量足夠大時才體現效果。資料量較小的 Collection 會直接進行精確檢索而不經過 ANN 索引,此時調整 search_list、use_refine、early_termination_threshold 對召回率與返回的 Distance 均無可觀測影響,參數調優應在接近生產規模的資料集上驗證。
Collection 的 Segment 數量過多會明顯影響查詢效能,建議定期通過管理頁面或用戶端 API 觸發 Compaction,降低 Segment 數量。