1、支持 MMap 的數據存儲
在 Milvus 中,內存映射文件允許將文件內容直接映射到內存中。這一功能提高了內存效率,尤其是在可用內存稀缺但完全加載數據不可行的情況下。這種優化機制可以增加數據容量,同時在一定限度內確保性能;但當數據量超出內存太多時,搜索和查詢性能可能會嚴重下降,因此請根據情況選擇打開或關閉此功能。
配置內存映射:從 Milvus 2.4 開始,您可以靈活調整靜態配置文件,在部署前為整個集群配置默認內存映射設置。此外,您還可以動態更改參數,以微調群集和索引級別的內存映射設置。展望未來,未來的更新將把內存映射功能擴展到字段級配置。
...
queryNode:mmap:# Set memory mapping property for whole clustermmapEnabled: false | true# Set memory-mapped directory path, if you leave mmapDirPath unspecified, the memory-mapped files will be stored in {localStorage.path}/ mmap by default. mmapDirPath: any/valid/path
....
自 2.4.10?之后,配置queryNode.mmap.mmapEnabled?分成以下四個獨立字段,所有默認值均為false?:
queryNode.mmap.vectorField, 控制向量數據是否為 mmap;
queryNode.mmap.vectorIndex控制向量索引是否為 mmap;
queryNode.mmap.scalarField控制標量數據是否為 mmap;
queryNode.mmap.scalarIndex控制標量索引是否為 mmap;
...
queryNode:mmap:vectorField: false # Enable mmap for loading vector datavectorIndex: false # Enable mmap for loading vector indexscalarField: false # Enable mmap for loading scalar datascalarIndex: false # Enable mmap for loading scalar index
....
此外,只能單獨為某個 Collections 打開或關閉向量索引和向量數據 mmap,而不能為其他 Collections 打開或關閉。
兼容性:如果原始配置queryNode.mmap.mmapEnabled?設置為true?,則此時新添加的配置將設置為true?。如果queryNode.mmap.mmapEnabled?設置為false?,如果新配置設置為true?,則最終值將為true
2、群集操作符期間:動態配置
在群集運行期間,可以在 Collections 或索引級別動態調整內存映射設置。
在Collections 層級,內存映射會應用到集合內所有未索引的原始數據,不包括主鍵、時間戳和行 ID。這種方法特別適用于大型數據集的綜合管理。
若要動態調整 Collections 中的內存映射設置,可使用set_properties()?方法。在這里,可以根據需要在True?或False?之間切換mmap.enabled?。
collection = Collection("test_collection") # Replace with your collection namecollection.set_properties({'mmap.enabled': True})
在 2.4.10?之后,可以使用add_field?方法調整 Collections 中的內存映射設置。在這里,可以根據需要在True?或False?之間切換mmap_enabled?
schema = MilvusClient.create_schema()schema.add_field(field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=768, mmap_enabled=True)
對于索引級設置,內存映射可專門應用于向量索引,而不會影響其他數據類型。對于需要優化向量搜索性能的 Collections 來說,這一功能非常寶貴。
要為 Collections 中的某個索引啟用或禁用內存映射,可調用alter_index()?方法,在index_name?中指定目標索引名稱,并將mmap.enabled?設置為True?或False
collection.alter_index(index_name="vector_index", # Replace with your vector index nameextra_params={"mmap.enabled": True} # Enable memory mapping for index
)
3、建議在哪些情況下啟用內存映射?啟用此功能后有哪些權衡?
內存有限或性能要求適中時,建議使用內存映射。啟用此功能可提高數據加載能力。例如,在 2 個 CPU 和 8 GB 內存的配置下,啟用內存映射比不啟用內存映射加載的數據多 4 倍。對性能的影響各不相同:
在內存充足的情況下,預期性能與只使用內存的情況類似。
如果內存不足,預期性能可能會下降。
Collection-level 和 Index-level 配置之間的關系是什么?
Collection-level 和 index-level 不是包含關系,Collection-level 控制原始數據是否啟用了 mmap,而 index-level 僅適用于向量索引。
有沒有推薦用于內存映射的索引類型?
有,建議使用 HNSW 啟用毫米映射。我們曾測試過 HNSW、IVF_FLAT、IVF_PQ/SQ 系列索引,IVF 系列索引的性能下降嚴重,而 HNSW 索引啟用毫米映射后的性能下降仍在預期之內。
內存映射需要什么樣的本地存儲?
高質量的磁盤可以提高性能,NVMe 驅動器是首選。
標量數據能否進行內存映射?
內存映射可應用于標量數據,但不適用于基于標量字段建立的索引。
如何確定不同級別內存映射配置的優先級?
在 Milvus 中,當跨多個級別明確定義內存映射配置時,索引級和 Collect 級配置共享最高優先級,然后是集群級配置。
如果我從 Milvus 2.3 升級,并配置了內存映射目錄路徑,會發生什么情況?
如果從 Milvus 2.3 升級并配置了內存映射目錄路徑 (mmapDirPath),您的配置將被保留,啟用內存映射的默認設置 (mmapEnabled) 將是true?。遷移元數據對同步現有內存映射文件的配置很重要。
4、Milvus為什么需要load整個index data到內存中,而不是類似MySQL這種傳統數據庫做分片加載
向量每個維度的值是float32,占用4個字節。每條1536維的向量占用的空間是6KB。1000條就是6MB,一百萬條6GB,一億條就是600GB,十億條就是6TB。這個是理論值。然后用不同的索引類型使用的內存關系如下:HNSW/IVF_FLAT ------------- 這兩種需要的內存和理論值基本相等IVF_SQ8/IVF_PQ-------------- 這兩種需要的內存大約相當于理論值的25%~30%
如果除了向量之外還有別的字段,比如Int64類型的字段,十億條就占用 十億乘以8字節 這么多空間。如果是VARCHAR類型,那就跟字符串的長度相關,由于是用UTF-8編碼,每個字符可能占用1~4字節。
所以,你基本可以按這個路子估計出任意數據所需的最小內存。
選擇占內存小的索引是最簡單的方法。降維也是一個方法,但降維的工具你要自己去找。
換索引類型
降維HNSW/IVF_FLAT更適用于高維向量且對內存和查詢速度有較高要求,而IVF_SQ8/IVF_PQ適用于大規模數據且能夠在較低的內存消耗下實現高效的近似最近鄰搜索。不知道這個對索引選用的說法對不對。像我這個大規模數據,感覺是得用IVF_SQ8/IVF_PQ去搞
IVF_SQ8對搜索精度有較大影響DiskANN需要高性能磁盤,并且對延遲有很大影響HNSW需要較多的內存使用你也可以直接使用Zilliz cloud的Capacity optimized 實例,目前是性價比比較高的選擇。1億向量大概只需要16CU,大概一萬多一個月