Milvus向量數據庫是什么?-CSDN博客
一、核心概念解析
1.1 基礎概念
1.1.1 Bitset(位集)
-
高效的數據表示方式,使用位數組替代傳統數據類型
-
默認情況下,位值根據特定條件設置為 0 或 1
1.1.2 通道機制
-
PChannel(物理通道):對應日志存儲主題,系統啟動時分配256個
-
VChannel(邏輯通道):代表集合中的分片,邏輯獨立但物理資源共享
1.1.3 數據組織結構
-
Collection(集合):相當于關系型數據庫中的表
-
Partition(分區):集合的物理劃分,減少讀取負載
-
Segment(段):自動創建的數據文件,分為增長段和封閉段
-
Sharding(分片):基于主鍵哈希的寫入負載分發機制
1.1.4 數據元素
-
Entity(實體):由字段組成的完整數據記錄,具備唯一主鍵
-
Field(字段):支持標量數據(數字、字符串)和向量數據
-
Embedding Vector:非結構化數據的特征抽象表示
1.1.5 系統依賴
-
etcd:元數據存儲
-
MinIO/S3:對象存儲
-
Pulsar:快照日志管理
1.2 向量索引
1.2.1 索引類型
-
內存索引:提升查詢性能,每個字段支持單一索引類型
-
ANNS索引:近似最近鄰搜索,平衡精度與效率
-
磁盤索引:需特定硬件和環境支持
1.2.2 索引分類
-
基于樹的索引
-
基于圖的索引
-
基于哈希的索引
-
基于量化的索引
1.2.3 數據預處理
-
歸一化處理:將向量轉換為范數為1,使內積等于余弦相似度
-
非結構化數據處理:通過AI/ML模型轉換為向量表示
二、連接配置
2.1 網絡配置
bash
# 默認端口配置
GRPC_PORT=19530 # SDK連接端口
REST_PORT=9091 # HTTP接口端口
2.2 客戶端連接
java
// 創建連接實例
public MilvusServiceClient createClient(String host, int port) {return new MilvusServiceClient(ConnectParam.newBuilder().withHost(host).withPort(port).build());
}// 連接使用示例
MilvusServiceClient client = createClient("localhost", 19530);// 資源釋放
client.close();
三、集合管理
3.1 集合創建模板
java
public CreateCollectionParam buildCollectionSchema() {// 主鍵字段FieldType idField = FieldType.newBuilder().withName("book_id").withDataType(DataType.Int64).withPrimaryKey(true).withAutoID(false).build();// 標量字段FieldType scalarField = FieldType.newBuilder().withName("word_count").withDataType(DataType.Int64).build();// 向量字段FieldType vectorField = FieldType.newBuilder().withName("book_intro").withDataType(DataType.FloatVector).withDimension(128) // 根據實際維度調整.build();return CreateCollectionParam.newBuilder().withCollectionName("book").withDescription("圖書向量數據庫").withShardsNum(2).addFieldType(idField).addFieldType(scalarField).addFieldType(vectorField).build();
}
3.2 集合操作工具方法
java
// 檢查集合存在性
public boolean collectionExists(MilvusServiceClient client, String collectionName) {R<Boolean> response = client.hasCollection(HasCollectionParam.newBuilder().withCollectionName(collectionName).build());return response.getData() == Boolean.TRUE;
}// 獲取集合統計信息
public void printCollectionStats(MilvusServiceClient client, String collectionName) {R<GetCollectionStatisticsResponse> response = client.getCollectionStatistics(GetCollectionStatisticsParam.newBuilder().withCollectionName(collectionName).build());GetCollStatResponseWrapper wrapper = new GetCollStatResponseWrapper(response.getData());System.out.println("總記錄數: " + wrapper.getRowCount());
}
四、數據操作
4.1 數據生成與插入
java
public List<InsertParam.Field> generateSampleData(int recordCount, int vectorDimension) {Random random = new Random();// 生成主鍵數據List<Long> ids = new ArrayList<>();for (long i = 0; i < recordCount; i++) {ids.add(i);}// 生成標量數據List<Long> wordCounts = new ArrayList<>();for (int i = 0; i < recordCount; i++) {wordCounts.add(10000L + i);}// 生成向量數據List<List<Float>> vectors = new ArrayList<>();for (int i = 0; i < recordCount; i++) {List<Float> vector = new ArrayList<>();for (int j = 0; j < vectorDimension; j++) {vector.add(random.nextFloat());}vectors.add(vector);}// 構建字段列表List<InsertParam.Field> fields = Arrays.asList(new InsertParam.Field("book_id", DataType.Int64, ids),new InsertParam.Field("word_count", DataType.Int64, wordCounts),new InsertParam.Field("book_intro", DataType.FloatVector, vectors));return fields;
}// 執行數據插入
public void insertData(MilvusServiceClient client, String collectionName, String partitionName, List<InsertParam.Field> fields) {InsertParam insertParam = InsertParam.newBuilder().withCollectionName(collectionName).withPartitionName(partitionName).withFields(fields).build();R<MutationResult> response = client.insert(insertParam);if (response.getStatus() != R.Status.Success.getCode()) {throw new RuntimeException("插入失敗: " + response.getMessage());}
}
4.2 索引管理
java
public void createVectorIndex(MilvusServiceClient client, String collectionName, String fieldName, IndexType indexType, MetricType metricType, String extraParams) {CreateIndexParam indexParam = CreateIndexParam.newBuilder().withCollectionName(collectionName).withFieldName(fieldName).withIndexType(indexType).withMetricType(metricType).withExtraParam(extraParams).withSyncMode(false).build();client.createIndex(indexParam);
}
五、查詢與搜索
5.1 混合搜索實現
java
public SearchResults hybridSearch(MilvusServiceClient client, String collectionName,List<List<Float>> queryVectors, String vectorFieldName,String filterExpr, int topK, String searchParams) {// 確保集合已加載client.loadCollection(LoadCollectionParam.newBuilder().withCollectionName(collectionName).build());SearchParam searchParam = SearchParam.newBuilder().withCollectionName(collectionName).withMetricType(MetricType.L2).withOutFields(Arrays.asList("book_id", "word_count")).withTopK(topK).withVectors(queryVectors).withVectorFieldName(vectorFieldName).withExpr(filterExpr).withParams(searchParams).build();R<SearchResults> response = client.search(searchParam);return response.getData();
}
5.2 向量查詢示例
java
public QueryResults queryByCondition(MilvusServiceClient client, String collectionName,String queryExpr, List<String> outputFields) {QueryParam queryParam = QueryParam.newBuilder().withCollectionName(collectionName).withConsistencyLevel(ConsistencyLevelEnum.STRONG).withExpr(queryExpr).withOutFields(outputFields).withOffset(0L).withLimit(100L).build();R<QueryResults> response = client.query(queryParam);return response.getData();
}
六、最佳實踐
6.1 性能優化建議
-
索引選擇:根據數據規模和查詢模式選擇合適的索引類型
-
內存管理:控制加載數據量不超過查詢節點總內存的90%
-
分區策略:合理使用分區減少讀取負載,分片分散寫入負載
6.2 錯誤處理機制
java
public <T> T executeWithRetry(MilvusOperation<T> operation, int maxRetries) {int attempt = 0;while (attempt < maxRetries) {try {return operation.execute();} catch (Exception e) {attempt++;if (attempt >= maxRetries) {throw new RuntimeException("操作失敗,重試次數耗盡", e);}try {Thread.sleep(1000 * attempt); // 指數退避} catch (InterruptedException ie) {Thread.currentThread().interrupt();throw new RuntimeException("操作被中斷", ie);}}}throw new RuntimeException("未知錯誤");
}interface MilvusOperation<T> {T execute();
}
七、完整示例
7.1 基礎操作流程
java
public class MilvusOperations {private MilvusServiceClient client;private String collectionName = "book";public void fullWorkflow() {// 1. 創建連接client = createClient("localhost", 19530);// 2. 創建集合CreateCollectionParam schema = buildCollectionSchema();client.createCollection(schema);// 3. 插入數據List<InsertParam.Field> data = generateSampleData(1000, 128);insertData(client, collectionName, "novel", data);// 4. 創建索引createVectorIndex(client, collectionName, "book_intro", IndexType.IVF_FLAT, MetricType.L2, "{\"nlist\":1024}");// 5. 執行搜索List<List<Float>> queryVector = Arrays.asList(generateRandomVector(128));SearchResults results = hybridSearch(client, collectionName, queryVector, "book_intro", "word_count <= 11000", 10, "{\"nprobe\":10}");// 6. 資源清理client.releaseCollection(ReleaseCollectionParam.newBuilder().withCollectionName(collectionName).build());client.close();}
}
八、依賴配置
8.1 Maven 配置
xml
<dependencies><dependency><groupId>io.milvus</groupId><artifactId>milvus-sdk-java</artifactId><version>2.2.1</version></dependency><!-- 可選:日志框架 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>2.0.7</version></dependency>
</dependencies>
8.2 配置建議
-
連接池配置:在生產環境中使用連接池管理Milvus連接
-
超時設置:根據網絡狀況調整操作超時時間
-
監控集成:集成監控系統跟蹤性能指標和錯誤率