.NET 原生駕馭 AI 新基建實戰系列(五):Milvus ── 大規模 AI 應用的向量數據庫首選
1. 引言
Milvus 是一個強大的工具,幫助開發者處理大規模向量數據,尤其是在人工智能和機器學習領域。它可以高效地存儲和檢索高維向量數據,適合需要快速相似性搜索的場景。在 .NET 環境中,開發者可以通過 Milvus C# SDK 輕松連接和操作 Milvus 服務器,包括創建集合、插入數據和執行搜索等操作。
- Milvus 是一個開源向量數據庫,專為 AI 和 ML 應用設計,支持高效相似性搜索。
- 它采用云原生架構,分為接入層、協調服務、工作節點和存儲四層,便于擴展。
- 在 .NET 中,可通過 Milvus C# SDK(當前為 2.3.0-preview.1)操作 Milvus,安裝簡單,功能包括創建集合、插入數據和搜索。
- Milvus 在圖像檢索、推薦系統和 NLP 等場景中表現優異,最新版本為 2.5.9(2025 年 4 月 14 日)。
- Milvus 在性能上通常優于其他向量數據庫,特別是在大規模數據處理中。
2. Milvus 概述
Milvus 是一個在 2019 年創建的開源向量數據庫,其主要目標是存儲、索引和管理由深度神經網絡和其他機器學習(ML)模型生成的大規模嵌入向量。它能夠處理萬億級別的向量索引,特別適用于非結構化數據的處理,例如圖像、視頻、音頻和自然語言等,這些數據占全球數據的約 80%。
Milvus 的設計原則是云原生,將存儲和計算分離,所有組件均為無狀態。
Milvus 支持多種索引和度量,適合不同的應用場景。以下是支持的索引類型及其適用場景:
| 索引類型 | 分類 | 最佳適用場景 |
|---|---|---|
| FLAT | 無 | 小規模(百萬級)數據集,追求精度 |
| IVF_FLAT | 無 | 平衡精度和查詢速度 |
| IVF_SQ8 | 量化-based | 資源受限,減少內存消耗 |
| IVF_PQ | 量化-based | 高查詢速度,犧牲一定精度 |
| HNSW | 圖-based | 高搜索效率需求 |
| HNSW_SQ | 量化-based | 有限內存,次優精度 |
| SCANN | 量化-based | 高速度、高召回,大內存 |
| BIN_FLAT | 量化-based | 二進制數據,小數據集,精確搜索 |
| SPARSE_INVERTED_INDEX | 倒排索引 | 稀疏向量,文本搜索 |
相似性度量包括歐幾里得距離(L2)、內積(IP)等,適用于浮點嵌入向量;對于二進制嵌入向量,支持漢明距離、Jaccard 距離等,特別適用于分子相似性搜索。
Milvus 還支持數據分區、分片、數據持久化、增量數據攝取、標量向量混合查詢和時間旅行等高級功能。這些特性增強了其在生產環境中的靈活性和可靠性。
3. 向量數據庫的概念與用例
向量數據庫是一種專門用于存儲和檢索高維向量的數據庫,優化了向量相似性搜索。它們通過近似最近鄰(ANN)算法高效地找到與查詢向量最相似的向量。這種能力在處理非結構化數據時尤為重要,因為非結構化數據(如電子郵件、照片、蛋白質結構)可以通過嵌入技術轉換為向量,從而進行相似性分析。
Milvus 架構圖
向量數據庫結合了傳統數據庫的能力和獨立向量索引的專門化,特別適合 AI 應用。Milvus 的典型應用場景包括:
這些場景展示了 Milvus 在 AI 應用中的廣泛適用性,尤其是在檢索增強生成(RAG)、語義搜索和混合搜索中。
4. Milvus 的架構與底層原理
Milvus 采用共享存儲架構,分離存儲和計算,確保計算節點具有水平擴展能力,其四層架構如下:
| 層級 | 功能描述 |
|---|---|
| 接入層 | 由無狀態代理組成,驗證客戶端請求,減少返回結果,使用負載均衡(如 Nginx、Kubernetes Ingress)。 |
| 協調服務 | 管理任務分配、集群拓撲、負載均衡、時間戳生成,包括 Root Coordinator、Query Coordinator、Data Coordinator。 |
| 工作節點 | 執行 DML 命令,無狀態,可在 Kubernetes 上擴展,包括查詢節點、數據節點和索引節點。 |
| 存儲 | 負責數據持久化,包括元數據存儲(etcd)、日志代理(Pulsar/RocksDB)、對象存儲(MinIO、S3)。 |
多層架構設計
4.1 數據處理流程
Milvus 的數據處理包括:
- 數據插入:通過代理路由請求到分片,使用時間戳確保順序,寫入日志序列。
- 索引構建:在索引節點上構建,支持 SIMD 加速,未來計劃支持異構計算。
- 數據查詢:查詢節點執行搜索,支持并發,分為增長段和密封段。
寫入路徑中的流程圖
4.2 索引機制
Milvus 支持多種索引類型,每種索引有特定的參數和適用場景。例如,HNSW 索引適合高搜索效率,IVF_FLAT 適合平衡精度和速度。參數包括 nlist、M、efConstruction 等,詳情見https://milvus.io/docs/index.md。
倒排索引圖
讀取路徑中的流程圖
5.Milvus 的高性能
5.1 設計理念和架構優化
Milvus 的高性能主要源于其獨特的設計理念和架構優化:
- 云原生架構與計算存儲分離:Milvus 采用云原生設計,將計算和存儲分離,所有組件無狀態,避免了資源競爭,提升了大規模數據處理能力。
- 優化的向量索引算法:Milvus 支持多種高效的向量索引(如 HNSW、IVF_FLAT、SCANN),基于近似最近鄰(ANN)算法,能在速度與精度間找到平衡,適合億級甚至萬億級向量搜索。
- 數據分區與并行處理:通過數據分區和分片,Milvus 將大數據集劃分為小塊,并行執行查詢,顯著降低延遲。
- 高效查詢處理:Milvus 針對向量搜索優化了查詢機制,配備獨立工作節點支持高并發,提升查詢效率。
- 硬件加速與擴展性:Milvus 充分利用現代硬件(如 GPU 加速)和分布式系統,通過 Kubernetes 等實現彈性擴展。
總的來說,Milvus 的高性能得益于其云原生架構、先進的索引技術、分布式設計以及硬件優化,能夠為現代 AI 應用提供低延遲和高吞吐量的支持。
5.2 性能測試
下圖是在 sift50m 數據集和 IVF_SQ8 索引上運行的測試結果,其中比較了不同nlist/nprobe 對的召回率和查詢性能。
準確性測試
性能測試
6. Semantic Kernel Vector Connectors 對 Milvus 的支持
6.1 向量連接器
Semantic Kernel Vector Connectors(簡稱“向量連接器”)是 Semantic Kernel 框架中的一類工具,專門設計用于將 Semantic Kernel 和向量數據庫進行連接和管理。向量數據庫是一種存儲高維向量數據的系統,這些向量通常是文本、圖像等數據的嵌入(embeddings),用于表示數據的語義特征。向量連接器作為橋梁,讓 Semantic Kernel 可以高效地存取這些向量數據,支持復雜的 AI 功能。
目前,Semantic Kernel 支持多種向量連接器,例如針對 Azure AI Search、Chroma、Milvus 和 Elasticsearch 等數據庫的連接器,每種連接器都針對特定數據庫優化,確保高效的數據操作。
6.2 主要功能
向量連接器為開發者提供了以下關鍵功能:
6.2.1 數據存儲與管理
向量連接器允許將嵌入向量存儲到向量數據庫中,并支持插入、更新和刪除操作。這些嵌入向量可以代表文本、圖像等多種數據類型,幫助開發者輕松管理數據。
6.2.2 高效檢索
向量連接器支持快速的向量檢索,例如通過近似最近鄰(ANN)搜索,找到與查詢向量最相似的向量。這一功能在語義搜索和推薦系統中尤為重要。
6.2.3 統一抽象
向量連接器提供了一個統一的接口,隱藏了底層向量數據庫的復雜性。開發者無需掌握每種數據庫的具體實現細節即可使用,大大簡化了開發過程。
6.3 典型應用場景
向量連接器在以下場景中表現出色:
6.3.1 語義搜索
在知識庫或文檔管理系統中,向量連接器可實現智能語義搜索。用戶輸入自然語言查詢(如“查找關于預算的文檔”),系統通過向量相似性返回相關結果。
6.3.2 推薦系統
在電商或內容平臺中,向量連接器可存儲用戶和物品的嵌入向量,通過計算相似度為用戶推薦相關產品或內容。
6.3.3 知識圖譜
向量連接器可用于存儲知識圖譜中的實體嵌入向量,支持語義查詢和推理,助力構建智能知識系統。
6.3 代碼演示
?Microsoft.SemanticKernel.Connectors.Milvus 實現更強大的 AI 應用開發,但是這個包尚處于Alpha版本,接口隨時可能會發生變化,大家現在只需要簡單的看一下,等待最終版的發布就行了。以下代碼由于該 Microsoft.SemanticKernel.Connectors.Milvus SDK 實現,此處只做Demo使用。
6.3.1 MilvusMemoryStore
MilvusMemoryStore store = new(Host{}, vectorSize: 5, port: {Port}, consistencyLevel: ConsistencyLevel.Strong);
6.3.2 創建集合
await this.store.CreateCollectionAsync("collection1");
6.3.3 插入數據
this.store.UpsertBatchAsync(CollectionName,
[
new MemoryRecord(
new MemoryRecordMetadata(
isReference: true,
id: "Some id",
description: "Some description",
text: "Some text",
externalSourceName: "Some external resource name",
additionalMetadata: "Some additional metadata"),
new[] { 10f, 11f, 12f, 13f, 14f },
key: "Some key",
timestamp: new DateTimeOffset(2023, 1, 1, 12, 0, 0, TimeSpan.Zero)),
new MemoryRecord(
new MemoryRecordMetadata(
isReference: false,
id: "Some other id",
description: "",
text: "",
externalSourceName: "",
additionalMetadata: ""),
new[] { 20f, 21f, 22f, 23f, 24f },
key: null,
timestamp: null),
]);
6.3.4 數據搜索
List<(MemoryRecord Record, double SimilarityScore)> results =
this.Store.GetNearestMatchesAsync(CollectionName, new[] { 5f, 6f, 7f, 8f, 9f }, limit: 2, withEmbeddings: withEmbeddings).ToEnumerable().ToList();
Assert.True(result.Value.SimilarityScore > 0);
MemoryRecord record = result.Value.Record;
Assert.Equal("Some other id", record.Metadata.Id);
Assert.Equal(
withEmbeddings ? [20f, 21f, 22f, 23f, 24f] : [],
record.Embedding.ToArray());
7. 官方 SDK 安裝與使用
?此處只做簡要演示,具體請看:http://www.rzrgm.cn/code-daily/p/18761132
首先,通過 NuGet 安裝 Milvus.Client 包。安裝命令如下:
dotnet add package Milvus.Client
安裝完成后,可以通過以下步驟開始操作:
7.1 連接到 Milvus 服務器
使用 MilvusClient 類創建客戶端實例。例如:
var milvusClient = new MilvusClient("localhost", username: "username", password: "password");
請確保替換 "localhost" 為實際的 Milvus 服務主機地址。
7.2 創建集合:
定義集合的 schema,包括字段類型和維度。例如,創建一個圖書搜索的集合:
string collectionName = "book";
MilvusCollection collection = milvusClient.GetCollection(collectionName);
//Check if this collection exists
var hasCollection = await milvusClient.HasCollectionAsync(collectionName);
if(hasCollection){
await collection.DropAsync();
Console.WriteLine("Drop collection {0}",collectionName);
}
await milvusClient.CreateCollectionAsync(
collectionName,
new[] {
FieldSchema.Create<long>("book_id", isPrimaryKey:true),
FieldSchema.Create<long>("word_count"),
FieldSchema.CreateVarchar("book_name", 256),
FieldSchema.CreateFloatVector("book_intro", 2L)
}
);
7.3 插入數據
Random ran = new ();
List<long> bookIds = new ();
List<long> wordCounts = new ();
List<ReadOnlyMemory<float>> bookIntros = new ();
List<string> bookNames = new ();
for (long i = 0L; i < 2000; ++i)
{
bookIds.Add(i);
wordCounts.Add(i + 10000);
bookNames.Add($"Book Name {i}");
float[] vector = new float[2];
for (int k = 0; k < 2; ++k)
{
vector[k] = ran.Next();
}
bookIntros.Add(vector);
}
MilvusCollection collection = milvusClient.GetCollection(collectionName);
MutationResult result = await collection.InsertAsync(
new FieldData[]
{
FieldData.Create("book_id", bookIds),
FieldData.Create("word_count", wordCounts),
FieldData.Create("book_name", bookNames),
FieldData.CreateFloatVector("book_intro", bookIntros),
});
// Check result
Console.WriteLine("Insert count:{0},", result.InsertCount);
7.4 創建索引
為向量字段創建索引以加速搜索。例如:
MilvusCollection collection = milvusClient.GetCollection(collectionName);
await collection.CreateIndexAsync(
"book_intro",
//MilvusIndexType.IVF_FLAT,//Use MilvusIndexType.IVF_FLAT.
IndexType.AutoIndex,//Use MilvusIndexType.AUTOINDEX when you are using zilliz cloud.
SimilarityMetricType.L2);
// Check index status
IList<MilvusIndexInfo> indexInfos = await collection.DescribeIndexAsync("book_intro");
foreach(var info in indexInfos){
Console.WriteLine("FieldName:{0}, IndexName:{1}, IndexId:{2}", info.FieldName , info.IndexName,info.IndexId);
}
// Then load it
await collection.LoadAsync();
}
7.5 加載集合并執行搜索
加載集合后,可以執行向量搜索。例如,搜索與查詢向量 [0.12217915, -0.034832448] 最相似的三部電影:
List<string> search_output_fields = new() { "book_id" };
List<List<float>> search_vectors = new() { new() { 0.1f, 0.2f } };
SearchResults searchResult = await collection.SearchAsync(
"book_intro",
new ReadOnlyMemory<float>[] { new[] { 0.1f, 0.2f } },
SimilarityMetricType.L2,
limit: 2);
// Query
string expr = "book_id in [2,4,6,8]";
QueryParameters queryParameters = new ();
queryParameters.OutputFields.Add("book_id");
queryParameters.OutputFields.Add("word_count");
IReadOnlyList<FieldData> queryResult = await collection.QueryAsync(
expr,
queryParameters);
這些操作展示了 Milvus 在 .NET 環境下的基本使用方法,開發者可以根據實際需求調整參數和數據。
8. 結語
Milvus 是一個功能強大的向量數據庫,特別適合需要高效向量相似性搜索的 AI 和 ML 應用。在 .NET 環境中,通過 Milvus C# SDK 或者 Semantic Milvus Connector,開發者可以輕松實現數據存儲、索引和檢索等操作。建議讀者參考官方文檔和社區資源進一步探索,例如 Milvus 官方文檔 和 Milvus C# SDK GitHub。
9.引用
- Milvus 官方文檔概述:https://milvus.io/docs/overview.md
- Milvus C# SDK GitHub 倉庫:https://github.com/milvus-io/milvus-sdk-csharp)
- Milvus 連接器 NuGet 包:https://www.nuget.org/packages/Microsoft.SemanticKernel.Connectors.Milvus)
- MilvusMemoryStoreTests:https://github.com/microsoft/semantic-kernel/blob/main/dotnet/src/IntegrationTests/Connectors/Memory/Milvus/MilvusMemoryStoreTests.cs
本文來自博客園,作者:AI·NET極客圈,轉載請注明原文鏈接:http://www.rzrgm.cn/code-daily/p/18851097
歡迎關注我們的公眾號,作為.NET工程師,我們聚焦人工智能技術,探討 AI 的前沿應用與發展趨勢,為你立體呈現人工智能的無限可能,讓我們共同攜手共同進步。

浙公網安備 33010602011771號