向量数据库详解
向量数据库是专为存储和检索高维向量(数值数组)而优化的数据库,广泛应用于AI语义检索、推荐系统等场景。与传统数据库不同,它通过相似度查找(如ANN算法)实现高效检索,支持混合查询(向量+结构化数据)。主流产品包括Milvus、Faiss等,具有分布式扩展、高性能索引等特点。典型操作包括向量插入、相似度搜索等,常与LLM结合实现RAG等智能应用。部署方式灵活,支持Docker、K8s等,提供多语言S
·
一、什么是向量数据库?
向量数据库(Vector Database)是一种专门为存储和检索高维向量(如 128、256、768 甚至数千维)而优化的数据库。
每个向量可以理解为一个有序的数值数组,通常由深度学习模型、特征工程、嵌入算法(如 word2vec、BERT、CLIP、ResNet 等)生成。
典型应用:
- 文本、图片、音频、视频的语义检索
- 推荐系统、相似内容查找
- AI Agent、RAG(检索增强生成)、知识库
二、向量数据库与传统数据库的区别
对比项 | 关系型/NoSQL数据库 | 向量数据库 |
---|---|---|
数据结构 | 表、文档、键值 | 向量(数组)+元数据 |
检索方式 | 精确查找/条件过滤 | 相似度查找(ANN) |
查询目标 | 结构化信息 | 语义相似、最近邻 |
性能优化 | 索引、分区 | 向量索引、分片、ANN |
适用场景 | 传统业务 | AI、推荐、语义搜索 |
三、核心技术原理
1. 高维向量存储
- 每条记录包含向量字段(如
[0.12, -0.98, ..., 0.56]
)和元数据(如ID、标签、原始内容等)。
2. 相似度检索(ANN)
- ANN(Approximate Nearest Neighbor)算法,如 HNSW、IVF、PQ、LSH 等。
- 通过向量之间的距离(如欧氏距离、余弦相似度)查找最相似的 K 个向量。
3. 向量索引
- 支持高效插入、删除、批量检索。
- 支持分片、分布式扩展,适合亿级向量规模。
4. 混合检索
- 支持向量检索与结构化过滤(如标签、时间范围)结合。
四、主流向量数据库产品
1. Milvus
- 开源、分布式、极高性能
- 支持多种 ANN 算法
- 提供 Python/Java/Go/REST 等接口
2. Faiss
- Facebook 开源库,专注于向量检索
- C++/Python接口,常嵌入自定义服务
3. Weaviate
- 开源,支持向量+结构化混合检索
- 内置多种模型、RESTful API
4. Pinecone
- 云原生、托管服务,易用性高
- 支持大规模部署
5. Qdrant
- 开源,专注于高效 ANN 检索
- 多语言API支持
6. Elasticsearch/OpenSearch 向量检索
- 传统搜索引擎扩展,适合与全文检索结合
五、典型应用场景
- AI 语义检索:文本、图片、视频的语义相似搜索
- 推荐系统:用户/物品特征向量检索,做个性化推荐
- RAG/知识库:LLM 检索增强生成,知识问答
- 异常检测/聚类分析:高维特征的聚类、异常点发现
- 多模态检索:跨文本、图像、音频的统一检索
六、基本操作与查询示例(以 Milvus 为例)
1. 插入向量
from pymilvus import Collection
# 创建集合
collection = Collection("demo") # 已定义 schema
# 插入向量
entities = [[0.12, -0.98, ..., 0.56], [0.23, -0.87, ..., 0.45]]
collection.insert(entities)
2. 相似度检索
# 查询与目标向量最相近的前5条
results = collection.search([[0.10, -0.90, ..., 0.50]], "embedding", params={"metric_type": "L2"}, limit=5)
for hit in results[0]:
print(hit.id, hit.distance)
3. 混合过滤检索
results = collection.search(
[[0.10, -0.90, ..., 0.50]],
"embedding",
limit=5,
expr="label == 'cat' and ts > 1680000000"
)
七、架构与性能优化
- 分布式扩展:支持多节点、分片、负载均衡
- 索引类型选择:根据数据规模、精度需求选 HNSW、IVF、PQ 等
- 批量写入/检索:提升吞吐量
- 混合检索:结合元数据和向量,提高业务相关性
- 缓存与预热:热点向量预加载,降低响应延迟
八、选型建议
- 亿级规模、高性能:Milvus、Pinecone、Qdrant
- 嵌入自定义服务:Faiss
- 结构化+向量混合:Weaviate、Elasticsearch/OpenSearch
- 云原生易用:Pinecone
- 开源本地部署:Milvus、Qdrant、Weaviate
九、向量数据库与 AI 的结合
向量数据库已成为 AI Agent、知识库、RAG 等新一代智能应用的核心基础设施。
它能让大模型“记住”海量知识、实现语义理解和推理,极大提升智能化水平。
十、Milvus 安装方式
1. Docker 一键安装(推荐)
适合个人开发、测试和小型生产环境。
# 下载官方 docker-compose 文件
wget https://github.com/milvus-io/milvus/releases/download/v2.3.12/milvus-standalone-docker-compose.yml -O docker-compose.yml
# 启动 Milvus
docker-compose up -d
# 查看服务状态
docker-compose ps
- 默认包含 Milvus Standalone(服务端)、MinIO(对象存储)、Etcd(元数据)、支持 REST/gRPC/Python/Java 等多种客户端。
- 默认端口:19530(gRPC),9091(HTTP REST)
2. 本地二进制安装
适合有特殊定制需求的场景。
- 下载 Milvus Release
- 解压后运行
milvus
可执行文件,需自行配置 MinIO、Etcd 等依赖。
3. 云/集群部署
- 支持 Kubernetes 部署(Helm Chart),适合大规模生产环境。
- 参考官方文档:Milvus Helm 部署
十一、Milvus 基本使用(Python为例)
1. 安装 Python SDK
pip install pymilvus
2. 连接 Milvus 服务
from pymilvus import connections
connections.connect("default", host="localhost", port="19530")
3. 创建 Collection(表)
定义 schema,包括主键和向量字段:
from pymilvus import FieldSchema, CollectionSchema, DataType, Collection
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=False),
FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=128)
]
schema = CollectionSchema(fields, description="向量检索测试")
collection = Collection("demo_collection", schema)
4. 插入向量数据
import numpy as np
ids = [1, 2, 3]
vectors = np.random.random((3, 128)).tolist()
collection.insert([ids, vectors])
5. 构建索引(提高检索效率)
index_params = {
"index_type": "IVF_FLAT", # 可选 HNSW、IVF_PQ 等
"metric_type": "L2", # 可选 COSINE、IP
"params": {"nlist": 128}
}
collection.create_index(field_name="embedding", index_params=index_params)
6. 向量检索
search_vectors = np.random.random((1, 128)).tolist()
results = collection.search(
search_vectors,
"embedding",
params={"metric_type": "L2", "nprobe": 10},
limit=5
)
for hit in results[0]:
print(f"id: {hit.id}, distance: {hit.distance}")
7. 结构化过滤/混合检索(如有其他字段)
results = collection.search(
search_vectors,
"embedding",
limit=5,
expr="id > 1"
)
8. 删除/更新数据
collection.delete("id in [2,3]")
十二、管理与运维
- 查看所有集合:
from pymilvus import list_collections; print(list_collections())
- 查看集合统计信息:
collection.num_entities
- 删除集合:
collection.drop()
- 备份与恢复:建议配合对象存储(MinIO)和定期快照
十三、常见问题与建议
- 端口防火墙:确保 19530、9091 端口开放
- 数据量大时:建议用分布式/集群部署,配置足够内存和存储
- 索引类型选择:HNSW 适合高精度召回,IVF_FLAT/IVF_PQ 适合大规模高效检索
- 与 AI 模型结合:推荐用 Milvus + embedding 服务,实现 RAG、语义检索等智能应用
十四、Milvus Java/Go 客户端示例
1. Java 客户端(milvus-sdk-java)
1.1 Maven 依赖
<dependency>
<groupId>io.milvus</groupId>
<artifactId>milvus-sdk-java</artifactId>
<version>2.3.4</version> <!-- 请使用 Milvus 官网最新版本 -->
</dependency>
1.2 基本操作示例
import io.milvus.client.*;
import io.milvus.grpc.DataType;
import java.util.Arrays;
import java.util.List;
public class MilvusDemo {
public static void main(String[] args) {
MilvusServiceClient milvusClient = new MilvusServiceClient(
ConnectParam.newBuilder()
.withHost("localhost")
.withPort(19530)
.build()
);
// 创建集合
FieldType idField = FieldType.newBuilder()
.withName("id")
.withDataType(DataType.Int64)
.withPrimaryKey(true)
.withAutoID(false)
.build();
FieldType vectorField = FieldType.newBuilder()
.withName("embedding")
.withDataType(DataType.FloatVector)
.withDimension(128)
.build();
CreateCollectionParam createCollectionReq = CreateCollectionParam.newBuilder()
.withCollectionName("java_demo")
.withDescription("Java Milvus Demo")
.withShardsNum(2)
.addFieldType(idField)
.addFieldType(vectorField)
.build();
milvusClient.createCollection(createCollectionReq);
// 插入数据
List<Long> ids = Arrays.asList(1L, 2L, 3L);
List<List<Float>> vectors = Arrays.asList(
Arrays.asList(0.1f, 0.2f, ...), // 128维向量
Arrays.asList(0.3f, 0.4f, ...),
Arrays.asList(0.5f, 0.6f, ...)
);
InsertParam insertParam = InsertParam.newBuilder()
.withCollectionName("java_demo")
.addField("id", ids)
.addField("embedding", vectors)
.build();
milvusClient.insert(insertParam);
// 检索
List<List<Float>> searchVectors = Arrays.asList(Arrays.asList(0.1f, 0.2f, ...));
SearchParam searchParam = SearchParam.newBuilder()
.withCollectionName("java_demo")
.withMetricType(MetricType.L2)
.withOutFields(Arrays.asList("id"))
.withTopK(5)
.withVectors(searchVectors)
.withVectorFieldName("embedding")
.withParams("{\"nprobe\":10}")
.build();
SearchResults searchResults = milvusClient.search(searchParam);
// 处理 searchResults...
milvusClient.close();
}
}
省略部分请用实际维度补全。更多细节见Milvus Java SDK文档。
2. Go 客户端(milvus-sdk-go)
2.1 安装
go get github.com/milvus-io/milvus-sdk-go/v2@latest
2.2 基本操作示例
package main
import (
"context"
"fmt"
"github.com/milvus-io/milvus-sdk-go/v2/client"
"github.com/milvus-io/milvus-sdk-go/v2/entity"
)
func main() {
ctx := context.Background()
cli, err := client.NewGrpcClient(ctx, "localhost:19530")
if err != nil {
panic(err)
}
defer cli.Close()
// 创建集合
schema := &entity.Schema{
CollectionName: "go_demo",
Description: "Milvus Go Demo",
Fields: []*entity.Field{
entity.NewField().
WithName("id").
WithDataType(entity.FieldTypeInt64).
WithIsPrimaryKey(true).
WithAutoID(false),
entity.NewField().
WithName("embedding").
WithDataType(entity.FieldTypeFloatVector).
WithDim(128),
},
}
err = cli.CreateCollection(ctx, schema, 2)
if err != nil {
panic(err)
}
// 插入数据
ids := entity.NewColumnInt64("id", []int64{1, 2, 3})
vectors := entity.NewColumnFloatVector("embedding", 128, [][]float32{
{0.1, 0.2, ...}, // 128维
{0.3, 0.4, ...},
{0.5, 0.6, ...},
})
_, err = cli.Insert(ctx, "go_demo", "", ids, vectors)
if err != nil {
panic(err)
}
// 检索
searchVec := [][]float32{{0.1, 0.2, ...}}
res, err := cli.Search(ctx, "go_demo", []string{}, "", []string{"embedding"}, searchVec, "embedding", entity.L2, 5, nil)
if err != nil {
panic(err)
}
fmt.Println(res)
// 更多API见官方[Go SDK文档](https://milvus.io/docs/go_sdk.md)
}
十五、分布式部署配置(Kubernetes Helm)
1. 前提
- 已有 Kubernetes 集群(如本地 minikube、云K8s)
- 已安装 Helm
2. 安装 Milvus Helm Chart
helm repo add milvus https://milvus-io.github.io/milvus-helm/
helm repo update
# 查看可用版本
helm search repo milvus
# 安装分布式集群
helm install my-milvus milvus/milvus --set cluster.enabled=true
3. 主要组件
- Milvus QueryNode/QueryCoord
- DataNode/DataCoord
- Proxy
- RootCoord
- Etcd、MinIO(元数据/对象存储)
4. 主要配置项
可通过 values.yaml
或 --set
参数自定义副本数、存储、资源等。
cluster:
enabled: true
queryNode:
replicaCount: 2
dataNode:
replicaCount: 2
minio:
persistence:
size: 100Gi
etcd:
replicaCount: 3
完整配置见官方 Helm 文档。
5. 访问方式
- 默认 Proxy 服务暴露 19530(gRPC)和 9091(REST)。
- 可通过 NodePort、LoadBalancer 或 Ingress 方式暴露到外部。
十六、与 LLM/知识库集成方案(RAG 实践)
1. 典型流程
- 知识分段
文档切分为段落/句子 - 向量生成
用 LLM embedding API(如 OpenAI、BGE、MiniLM)将文本转为向量 - 入库
向量+原文/元数据存入 Milvus - 检索增强生成
用户提问 → 生成向量 → Milvus 检索相似文本 → 拼接上下文 → LLM生成答案
2. Python 端到端示例
import openai
from pymilvus import Collection, connections
# 1. 连接 Milvus
connections.connect("default", host="localhost", port="19530")
collection = Collection("knowledge_base")
# 2. 用户提问
question = "什么是向量数据库?"
q_emb = openai.Embedding.create(model="text-embedding-ada-002", input=question)["data"][0]["embedding"]
# 3. 检索相关知识段
results = collection.search([q_emb], "embedding", limit=5)
context = "\n".join([hit.entity.get("content") for hit in results[0]])
# 4. 拼接上下文给大模型
prompt = f"已知知识:{context}\n请回答:{question}"
answer = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}])
print(answer["choices"][0]["message"]["content"])
3. Java/Go 集成建议
- 用 Java/Go SDK 负责与 Milvus 交互(入库、检索)。
- 用 HTTP 调用 LLM 服务(如 OpenAI、ChatGLM、Qwen、BGE等)。
- 构建微服务架构,支持高并发请求。
知识传递,互通有无,创作不易,点点关注!
更多推荐
所有评论(0)