分層儲存概述Compatible with Milvus 2.6.4+
在 Milvus 中,傳統的全載模式要求每個 QueryNode 在初始化時載入段的所有資料欄位和索引,即使是可能永遠不會被存取的資料。這可確保資料的即時可用性,但通常會造成資源浪費,包括高記憶體使用率、大量磁碟活動以及顯著的 I/O 開銷,尤其是在處理大型資料集時。
分層儲存透過將資料快取與區段載入解耦來解決這個挑戰。Milvus 不再一次載入所有資料,而是引進一個快取層,區分熱資料 (本機快取) 和冷資料 (遠端儲存)。QueryNode 現在最初只載入輕量級的元資料,並依需求動態拉取或驅逐欄位資料。這可大幅縮短載入時間、最佳化本機資源利用率,並使 QueryNode 能夠處理遠遠超過其實體記憶體或磁碟容量的資料集。
在下列情況下,請考慮啟用分層儲存:
超過單一 QueryNode 可用記憶體或 NVMe 容量的資料集
分析或批次工作負載,其中較快的載入速度比首次查詢延遲更為重要
混合型工作負載,可容忍不常存取資料偶爾發生的快取遺漏
元資料包括模式、索引定義、主塊映射、行數以及遠端物件的參照。這類型的資料較小,永遠都會快取,而且永遠不會被驅逐。
如需關於區段和區塊的詳細資訊,請參閱區段。
如何運作
分層儲存改變了 QueryNode 管理區段資料的方式。QueryNode 現在不再在載入時快取每個欄位和索引,而是只載入元資料,並使用快取層動態取得和驅逐資料。
全載模式與分層儲存模式的比較
雖然全載模式和分層儲存模式都處理相同的資料,但它們在 QueryNode 快取這些元件的時間和方式上有所不同。
全載模式:在載入時,QueryNode 會從物件儲存區快取完整的集合資料,包括元資料、欄位資料和索引。
分層儲存模式:在載入時,QueryNode 只快取元資料。欄位資料會以小塊粒度按需取得。索引檔案會保持遠端狀態,直到第一次查詢需要它們為止;然後會取得並快取整個每區段索引。
下圖顯示這些差異。
完整載入模式 Vs 分層儲存模式
查詢節點載入工作流程
在分層儲存模式下,工作流程有這些階段:
查詢節點載入工作流程
階段 1:懶惰載入
在初始化時,Milvus 執行懶惰載入,僅快取段層級的元資料,例如模式定義、索引資訊和群組對應。
在此階段不會快取實際欄位資料或索引檔案。這可讓集合在啟動後幾乎立即變得可查詢,同時保持最低的記憶體和磁碟消耗。
由於欄位資料和索引檔案會保留在遠端儲存中,直到第一次存取為止,因此第一次查詢可能會經歷額外的延遲,因為所需的資料必須按需求取得。為了減輕關鍵欄位或索引的這種影響,您可以使用「預熱」策略,在區段變為可查詢之前主動預先載入這些資料。
設定
啟用分層儲存時會自動套用。不需要手動設定。
第二階段:預熱
為了減少因懶惰負載所引發的首次命中延遲,Milvus 提供了預熱機制。
在段變為可查詢之前,Milvus 可以主動從物件儲存取得並快取特定欄位或索引,確保第一次查詢直接命中快取資料,而不是觸發隨選載入。
在暖機期間,欄位會在區塊層級預先載入,而索引則會在區段層級預先載入。
設定
暖機設定在milvus.yaml 的「分層儲存」區段中定義。您可以啟用或停用每個欄位或索引類型的預載,並指定偏好的策略。有關詳細設定,請參閱「預熱」。
第 3 階段:部分載入
一旦開始查詢或搜尋,QueryNode 會執行部分載入,僅從物件儲存中取得所需的資料區塊或索引檔案。
欄位:按需求載入資料塊層級。僅擷取符合目前查詢條件的資料區塊,以減少 I/O 和記憶體的使用。
索引:在區段層級依需求載入。索引檔案必須以完整單位取得,且不能分割為不同的區塊。
設定
啟用分層儲存時,會自動套用部分載入。不需要手動設定。若要盡量減少關鍵資料的首次命中延遲,請結合「預熱」。
第四階段:驅逐
為了維持健康的資源使用,Milvus 會在達到特定臨界值時自動釋放未使用的快取資料。
遷出遵循最近最少使用 (LRU)政策,確保不常存取的資料會先被移除,而有效資料則保留在快取記憶體中。
遷出受下列可設定項目約束:
浮水印:定義觸發和停止驅逐的記憶體或磁碟臨界值。
快取 TTL:在定義的不活動持續時間後移除過時的快取資料。
設定
在milvus.yaml 中啟用和調整驅逐參數。詳細設定請參閱驅逐。
開始使用
先決條件
Milvus 2.6.4 以上
具有專用記憶體和磁碟資源的 QueryNodes
物件儲存後端 (S3、MinIO 等)
QueryNode 資源不應與其他工作負載共享。共用資源會導致 Tiered Storage 錯誤判斷可用容量,導致當機。
基本配置範本
編輯 Milvus 配置檔案 (milvus.yaml) 以設定 Tiered Storage 設定:
# milvus.yaml
queryNode:
segcore:
tieredStorage:
# Warm Up Configuration
warmup:
scalarField: sync # Preload scalar field data
scalarIndex: sync # Preload scalar indexes
vectorField: disable # Don't preload vector field data (large)
vectorIndex: sync # Preload vector indexes
# Eviction Configuration
evictionEnabled: true
backgroundEvictionEnabled: true
# Memory Watermarks
memoryLowWatermarkRatio: 0.75 # Stop evicting at 75%
memoryHighWatermarkRatio: 0.80 # Start evicting at 80%
# Disk Watermarks
diskLowWatermarkRatio: 0.75
diskHighWatermarkRatio: 0.80
# Cache TTL (7 days)
cacheTtl: 604800
下一步
設定預熱- 優化存取模式的預載。請參閱「預熱」。
Tune Eviction- 為您的資源限制設定適當的水印和 TTL。請參閱驅逐。
監控效能- 追蹤快取點擊率、遷出頻率和查詢延遲模式。
迭代組態- 根據觀察到的工作負載特性調整設定。
常見問題
我可以在執行時變更分層儲存參數嗎?
不可以。所有參數必須在啟動 Milvus 之前在milvus.yaml 設定。變更需要重新啟動才能生效。
分層儲存會影響資料持久性嗎?
不會。資料持久性仍由遠端物件儲存處理。Tiered Storage 只管理 QueryNodes 上的快取。
使用 Tiered Storage,查詢速度是否總是更快?
不一定。Tiered Storage 可以減少載入時間和資源使用量,但接觸未快取(冷)資料的查詢可能會出現較高的延遲。對於延遲敏感的工作負載,建議使用全載模式。
為什麼即使啟用了分層儲存,QueryNode 仍會耗盡資源?
兩個常見原因:
QueryNode 配置的資源太少。水印是相對於可用資源而言的,因此配置不足會擴大錯誤的判斷。
QueryNode 資源與其他工作負載共享,因此 Tiered Storage 無法正確評估實際可用容量。
要解決這個問題,我們建議您為 QueryNode 分配專用資源。
為什麼有些查詢在高併發下會失敗?
如果太多查詢同時命中熱資料,QueryNode 的資源限制仍可能會被超出。有些線程可能會因為資源預留超時而失敗。在負載降低後重試,或分配更多的資源,可以解決這個問題。
啟用分層儲存後,為何搜尋/查詢延遲會增加?
可能的原因包括
頻繁查詢冷資料,而冷資料必須從儲存中取得。
水印設定得太靠近,造成頻繁的同步驅逐。