Milvus 向量数据库详细介绍
1. 什么是 Milvus?
Milvus 是一个开源的 向量数据库,专门为 AI 应用设计,用于高效存储、检索和分析海量向量数据。它支持:
相似性搜索:通过计算向量距离(如欧氏距离、余弦相似度等)找到最相似的向量
高性能:优化了大规模向量检索,支持十亿级向量毫秒级查询
多种索引类型:IVF_FLAT、HNSW、ANNOY、SCANN 等
混合查询:支持向量 + 标量数据的联合过滤查询
2. 核心组件
3. 典型应用场景
图像/视频检索
推荐系统
自然语言处理(语义搜索)
分子结构搜索
欺诈检测
完整 Docker Compose 配置(Milvus + Attu)
version: '3.5'
services:
# 元数据存储
etcd:
container_name: milvus-etcd
image: quay.io/coreos/etcd:v3.5.5
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
volumes:
- etcd_data:/etcd
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
# 对象存储
minio:
container_name: milvus-minio
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
environment:
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
volumes:
- minio_data:/minio_data
command: minio server /minio_data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
# Milvus 单机版
standalone:
container_name: milvus-standalone
image: milvusdb/milvus:v2.5.4
command: ["milvus", "run", "standalone"]
environment:
- ETCD_ENDPOINTS=etcd:2379
- MINIO_ADDRESS=minio:9000
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
- COMMON_STORAGETYPE=minio
volumes:
- milvus_data:/var/lib/milvus
ports:
- "19530:19530" # Milvus 服务端口
- "9091:9091" # 监控端口
depends_on:
- "etcd"
- "minio"
# 可视化界面
attu:
container_name: milvus-attu
image: zilliz/attu:v2.5.4
environment:
- MILVUS_URL=standalone:19530
- ATTU_USERNAME=admin # 可选:设置登录用户名
- ATTU_PASSWORD=admin123 # 可选:设置登录密码
ports:
- "8000:3000"
depends_on:
- standalone
restart: unless-stopped
volumes:
etcd_data:
minio_data:
milvus_data:使用说明
启动所有服务:
docker-compose up -d访问服务:
Milvus:通过
localhost:19530连接Attu 界面:浏览器打开
http://localhost:8000如果设置了用户名/密码,使用
admin/admin123登录连接地址填写
standalone:19530(容器内网络)或host.docker.internal:19530(Docker 特殊域名)
数据持久化:
所有数据保存在 Docker volumes 中:
docker volume ls
版本升级: 修改镜像版本号后重新启动:
image: milvusdb/milvus:v2.5.4 # 修改版本号 image: zilliz/attu:v2.5.4 # Attu 版本需与 Milvus 匹配
关键配置说明
MinIO 配置:
environment: - MINIO_ACCESS_KEY=minioadmin # 生产环境应修改 - MINIO_SECRET_KEY=minioadmin # 生产环境应修改Milvus 性能调优:
environment: - KNOWHERE_MAX_PARTITION_NUM=256 # 最大分区数 - KNOWHERE_USE_BLAS_THRESHOLD=20 # BLAS 加速阈值Attu 安全配置:
environment: - ATTU_DISABLE_TELEMETRY=true # 禁用数据统计 - HTTPS_ENABLED=true # 启用 HTTPS(需配置证书)
常见问题解决
连接问题:
如果 Attu 无法连接 Milvus,尝试将
MILVUS_URL改为:environment: - MILVUS_URL=host.docker.internal:19530
数据清理:
docker-compose down -v # 删除所有容器和 volumes性能监控:
Prometheus 监控端点:
http://localhost:9091/metrics
如何使用向量数据库
使用Python调用Ollama中的BAAI/bge-m3模型进行向量处理
要使用Python调用Ollama中已部署的BAAI/bge-m3模型进行向量处理,你可以按照以下步骤操作:
前提条件
确保Ollama服务已安装并运行
已通过Ollama部署了BAAI/bge-m3模型(可以使用
ollama pull BAAI/bge-m3命令拉取模型)
使用Ollama Python库
import ollama
# 连接到本地Ollama服务
client = ollama.Client(host='http://localhost:11434') # 默认端口
# 文本向量化
def get_embeddings(text):
response = client.embeddings(
model="BAAI/bge-m3",
prompt=text
)
return response['embedding']
# 示例使用
text = "这是一个测试句子"
embedding = get_embeddings(text)
print(f"向量维度: {len(embedding)}")
print(f"前10维向量值: {embedding[:10]}")批量处理文本
如果需要处理多个文本:
texts = ["第一条文本", "第二条文本", "第三条文本"]
# 使用LangChain方式
batch_embeddings = embeddings.embed_documents(texts)
# 或者使用基础API方式
batch_embeddings = [get_embeddings(text) for text in texts]注意事项
BAAI/bge-m3模型生成的向量维度通常是1024维
确保Ollama服务有足够的内存资源运行模型
对于长文本,可能需要先进行分块处理
生产环境中建议添加错误处理和重试机制
向 Milvus 集合增加数据的完整指南
要向 Milvus 向量数据库中的集合(Collection)添加数据,你需要遵循以下步骤。我将提供 Python 示例代码,假设你已经安装了必要的库并配置了 Milvus 连接。
准备工作
首先确保已安装必要的 Python 库:
bash
复制
pip install pymilvus基本数据插入流程
1. 连接到 Milvus 服务器
from pymilvus import connections, Collection
# 连接到 Milvus 服务器
connections.connect(
alias="default",
host='localhost', # Milvus 服务器地址
port='19530' # 默认端口
)2. 获取目标集合
# 获取已存在的集合
collection = Collection("your_collection_name") # 替换为你的集合名3. 准备要插入的数据
假设你的集合有以下字段:
id: 主键 (INT64)embedding: 向量字段 (FLOAT_VECTOR)title: 标量字段 (VARCHAR)
import random
# 示例数据 - 替换为你的实际数据
data = [
[1, 2, 3], # IDs
[[random.random() for _ in range(768)] for _ in range(3)], # 向量列表
["文档1", "文档2", "文档3"] # 标量字段
]4. 插入数据
# 插入数据
insert_result = collection.insert(data)
# 输出插入结果
print(f"成功插入 {len(insert_result.primary_keys)} 条数据")
print(f"插入的主键: {insert_result.primary_keys}")完整示例代码
from pymilvus import connections, Collection
import random
def insert_to_milvus():
# 1. 连接 Milvus
connections.connect(
alias="default",
host='localhost',
port='19530'
)
# 2. 获取集合
collection_name = "your_collection_name"
collection = Collection(collection_name)
# 3. 准备数据
num_entities = 5 # 插入5条数据
dim = 768 # 向量维度
ids = [i for i in range(1000, 1000+num_entities)] # 生成ID
embeddings = [[random.random() for _ in range(dim)] for _ in range(num_entities)]
titles = [f"文档{i}" for i in range(1, num_entities+1)]
data = [
ids,
embeddings,
titles
]
# 4. 插入数据
try:
insert_result = collection.insert(data)
print(f"成功插入 {len(insert_result.primary_keys)} 条数据")
print(f"插入的主键: {insert_result.primary_keys}")
# 可选:刷新使新插入的数据可立即搜索
collection.flush()
return True
except Exception as e:
print(f"插入数据失败: {e}")
return False
finally:
# 5. 断开连接
connections.disconnect("default")
if __name__ == "__main__":
insert_to_milvus()高级用法
批量插入大量数据
对于大量数据,建议分批插入:
batch_size = 1000 # 每批插入1000条
total_data = 10000 # 总共要插入的数据量
for i in range(0, total_data, batch_size):
batch_ids = [j for j in range(i, i+batch_size)]
batch_embeddings = [[random.random() for _ in range(dim)] for _ in range(batch_size)]
batch_titles = [f"文档{j}" for j in range(i, i+batch_size)]
collection.insert([batch_ids, batch_embeddings, batch_titles])
# 每插入10批刷新一次
if i % (10*batch_size) == 0:
collection.flush()使用 DataFrame 插入数据
如果你的数据在 Pandas DataFrame 中:
import pandas as pd
# 假设 df 是你的 DataFrame,包含 id, embedding 和 title 列
df = pd.DataFrame({
'id': [1, 2, 3],
'embedding': [[0.1]*768, [0.2]*768, [0.3]*768],
'title': ["doc1", "doc2", "doc3"]
})
# 转换为 Milvus 需要的格式
data = [
df['id'].tolist(),
df['embedding'].tolist(),
df['title'].tolist()
]
collection.insert(data)注意事项
数据类型匹配:确保你插入的数据类型与集合 schema 中定义的类型完全匹配
主键唯一性:主键字段的值必须是唯一的
向量维度:向量数据的维度必须与集合定义中的维度一致
刷新操作:插入后调用
flush()可以使新数据立即可搜索,但会带来性能开销性能考虑:大批量插入时建议关闭自动刷新 (
auto_flush=False)
指定数据库插入数据
在 Milvus 2.x(版本 2.5.6)中,数据库(Database) 是 Milvus 2.0 引入的多租户概念,允许在单个 Milvus 实例中创建多个逻辑隔离的数据库。以下是 指定数据库插入数据 的完整写法:
1. 初始化客户端时指定数据库
from pymilvus import MilvusClient
# 连接到指定数据库(默认数据库名为 "default")
client = MilvusClient(
uri="http://localhost:19530",
db_name="your_database_name" # 指定目标数据库
)2. 完整插入数据示例
假设数据库 my_db 中存在集合 products,字段包括:
id(主键)vector(512维向量)name(字符串)price(浮点数)
from pymilvus import MilvusClient
import numpy as np
# 初始化客户端并指定数据库
client = MilvusClient(
uri="http://localhost:19530",
db_name="my_db" # 指定目标数据库
)
# 准备要插入的数据
data = [
{
"id": 1001,
"vector": np.random.rand(512).tolist(), # 生成随机向量
"name": "无线耳机",
"price": 299.99
},
{
"id": 1002,
"vector": np.random.rand(512).tolist(),
"name": "智能手表",
"price": 599.50
}
]
# 插入数据到指定集合
insert_result = client.insert(
collection_name="products",
data=data
)
print(f"插入成功,主键: {insert_result['primary_keys']}")3. 关键注意事项
1) 数据库必须已存在
首次使用前需要手动创建数据库(通过 Attu 管理界面或 Milvus 命令行工具)
创建数据库的 SQL 命令:
CREATE DATABASE my_db;
2) 集合可以自动创建
如果
products集合不存在,Milvus 会根据首次插入的数据 自动推断 Schema但建议预先明确定义 Schema 以保证字段类型正确:
# 手动创建集合(可选) client.create_collection( collection_name="products", dimension=512, # 向量维度 primary_field_name="id", vector_field_name="vector", auto_id=False # 允许手动指定主键 )
3) 跨数据库操作
切换数据库需要创建新的客户端实例:
# 切换到另一个数据库 client_db2 = MilvusClient( uri="http://localhost:19530", db_name="another_db" )
4. 完整工作流程示例
from pymilvus import MilvusClient
import numpy as np
def insert_to_milvus():
# 1. 连接到指定数据库
client = MilvusClient(
uri="http://localhost:19530",
db_name="ecommerce_db" # 指定电商数据库
)
# 2. 准备测试数据
products = [
{"id": 2001, "name": "4K电视", "price": 3999.0, "category": "家电",
"vector": np.random.rand(512).tolist()},
{"id": 2002, "name": "游戏笔记本", "price": 8999.0, "category": "数码",
"vector": np.random.rand(512).tolist()}
]
# 3. 插入数据
try:
res = client.insert(
collection_name="products",
data=products
)
print(f"插入成功,主键: {res['primary_keys']}")
# 4. 验证插入
queried = client.get(
collection_name="products",
ids=[2001]
)
print(f"查询结果: {queried}")
except Exception as e:
print(f"操作失败: {e}")
if __name__ == "__main__":
insert_to_milvus()5. 通过 Attu 管理界面验证
访问
http://localhost:3000(Attu 默认端口)在顶部选择目标数据库(如
ecommerce_db)查看
products集合中的数据
常见问题解决
Q1: 报错 Database not found
确认数据库已创建:
SHOW DATABASES;检查拼写是否一致(区分大小写)
Q2: 字段类型不匹配
首次插入时会自动推断类型,后续插入必须兼容
建议预先明确定义 Schema
Q3: 如何列出所有数据库? 目前需要通过 Milvus 命令行或 Attu 界面查看,Python SDK 暂未直接提供此接口。