Milvus 是一个专为存储、索引和管理由深度神经网络和其他机器学习模型生成的大规模嵌入向量的向量数据库。它能够处理万亿规模的向量索引,支持多种索引类型和相似度度量,适用于图像、视频、音频等相似性搜索以及推荐系统等多种应用场景。
Milvus 基本介绍
- Milvus 由 Zilliz 开发,并捐赠给了 Linux 基金会下的 LF AI & Data 基金会,现已成为世界领先的开源向量数据库项目之一
- 什么是向量数据库:传统的数据库主要处理结构化数据,而向量数据库则专注于处理非结构化数据经过嵌入模型(embedding model)转换而来的向量数据。这些向量是高维空间中的点,它们捕获了原始数据的语义信息。向量数据库的核心能力是进行
相似性搜索
,即根据查询向量找到最相似的向量,从而实现语义级别的搜索和匹配。
- Milvus 采用 Apache 2.0 许可发布,大多数贡献者都是高性能计算(HPC)领域的专家,擅长构建大规模系统和优化硬件感知代码
Milvus 的核心特性
高性能和高扩展性:
Milvus 从设计之初就考虑了高效的向量数据库系统。它使用 C++ 作为其搜索引擎的核心组件,并集成了大量的硬件感知代码优化,以充分利用硬件能力。它支持从笔记本电脑到大规模分布式系统的各种部署环境,能够处理万亿规模的向量。
面向列存储:
Milvus 采用面向列的存储方式,在执行查询时只读取查询中涉及的特定字段,大大减少了访问的数据量,并支持列数据的向量化操作,提高了性能。
多样的搜索类型:
ANN 搜索(Approximate Nearest Neighbor):
查找最接近查询向量的前 K 个向量。
过滤搜索:
在指定的过滤条件下执行 ANN 搜索。
范围搜索:
查找查询向量指定半径范围内的向量。
混合搜索:
基于多向量领域进行 ANN 搜索。
全文搜索(Milvus 2.5 新增):
支持基于 BM25 的关键词搜索,与语义搜索功能互补。
可调整的一致性模型:
Milvus 提供多种一致性级别,可以在数据新鲜度和搜索性能之间进行权衡。
数据隔离与资源控制:
支持多租户场景下的数据隔离和资源管理。
丰富的索引算法:
支持多种可调整的索引和搜索算法(如 HNSW、DiskANN 等),可针对不同场景优化性能。
易用性:
提供丰富的 SDK (Python, Java, Go, Node.js 等) 和直观的 Web UI (Attu),简化开发和管理。
开源:
Milvus 是 LF AI & Data Foundation 下的开源项目,以 Apache 2.0 许可发布。
Milvus 的应用场景
图片/视频/音频相似性搜索:
例如,通过图片搜索相似的图片,或通过一段音乐搜索相似的音乐。
推荐系统:
根据用户行为和偏好推荐相似的商品、内容或用户。
智能问答系统 (Q&A):
根据用户提出的问题,在知识库中查找语义最相关的答案。
语义搜索:
理解用户搜索背后的含义,而不仅仅是匹配准确的单词。
重复数据删除:
识别并删除重复的图片、视频或文档。
网络安全:
异常行为检测、欺诈检测等。
Docker 部署 Milvus
Milvus 提供了多种部署方式,其中使用 Docker Compose 是最简单快捷的方式,适合本地开发和测试。
前提条件
- 已安装 Docker Desktop (推荐,包含了 Docker Engine 和 Docker Compose)
- 确保您的系统已启用虚拟化(在 Windows 上通常需要在 BIOS/UEFI 中开启)
Milvus Standalone 部署
-
下载 Docker Compose 配置文件:
Milvus 官方提供了 Docker Compose 配置文件。可以通过以下命令下载最新版本的配置文件(更多配置文件参考):
wget https://raw.githubusercontent.com/milvus-io/milvus/refs/heads/master/deployments/docker/standalone/docker-compose.yml -O docker-compose.yml
-
配置说明:docker-compose.yml
文件中包含了 Milvus 服务及其依赖(如 etcd, MinIO)的配置,端口:
- milvus: 19530/9091
- minio: 9000/9001
- etcd: 2379
-
启动 Milvus:
在 docker-compose.yml
文件所在的目录下,运行以下命令启动 Milvus:
# `-d` 参数表示在后台运行
docker-compose up -d
# 检查 Milvus 状态,确定 `milvus-standalone`、`etcd` 和 `minio` 等容器都处于 `Up` 状态
docker-compose ps
-
(可选)安装 Attu (Milvus Web UI):
Attu 是一个用于 Milvus 可观察性和管理的直观 Web 界面。
docker pull zilliz/attu:latest
docker run -p 3000:3000 zilliz/attu:latest
然后访问 http://<host-ip>:3000
并在 Attu 界面中连接到您的 Milvus 实例(默认地址通常是 <host-ip>:19530
)
Milvus 使用
使用 Milvus 通常通过其提供的 SDK(如 PyMilvus)进行。以下是一个使用 PyMilvus 的基本示例:
安装 PyMilvus
Python 基本使用示例
from pymilvus import MilvusClient, DataType, FieldSchema, CollectionSchema, Collection
# 1. 连接到 Milvus 实例
# 假设 Milvus 在本地的 19530 端口运行
client: MilvusClient = MilvusClient(uri="http://100.80.0.132:19530")
# 2. 定义 Collection 的 Schema
# Collection 类似于传统数据库中的表,用于存储具有相同结构的向量数据。
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=False),
FieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=128), # 假设向量维度是 128
FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=512) # 附加的标量字段
]
schema = CollectionSchema(fields, description="This is my first Milvus collection")
# 3. 创建 Collection
collection_name = "my_test_collection"
if client.has_collection(collection_name=collection_name):
client.drop_collection(collection_name=collection_name) # 如果已存在则删除
client.create_collection(collection_name=collection_name, schema=schema)
# 4. 准备数据并插入
# 实际应用中,这些向量会由深度学习模型生成
import random
data = []
for i in range(100):
data.append({
"id": i,
"vector": [random.random() for _ in range(128)], # 实际需要替换为 embedding 后的向量,否则查询不到数据
"text": f"This is text number {i}"
})
res = client.insert(collection_name=collection_name, data=data)
print(f"Inserted entities: {res}")
# 5. 创建索引
# 索引是进行高效相似性搜索的关键
index_params = client.prepare_index_params()
index_params.add_index(
field_name="vector",
index_type="IVF_FLAT", # 索引类型,例如 IVF_FLAT, HNSW
metric_type="L2", # 距离度量,例如 L2, COSINE
params={"nlist": 128} # 索引参数
)
client.create_index(collection_name=collection_name, index_params=index_params)
print("Index created.")
# 6. 加载 Collection (在进行搜索前必须加载)
client.load_collection(collection_name=collection_name)
print("Collection loaded.")
# 7. 执行向量搜索
query_vector = data[0].get('vector') # 查询向量
search_results = client.search(
collection_name=collection_name,
data=[query_vector],
limit=5, # 返回前 5 个最相似的结果
output_fields=["text"] # 返回结果中包含 'text' 字段
)
print(f"\nSearch Results: {search_results}")
for hit in search_results[0]:
print(f"ID: {hit['id']}, Distance: {hit['distance']}, Text: {hit['text']}")
# 8. (可选)执行过滤搜索
filter_search_results = client.search(
collection_name=collection_name,
data=[query_vector],
limit=3,
filter="id > 50", # 过滤条件,只搜索 id 大于 50 的实体
output_fields=["text"]
)
print("\nFiltered Search Results (id > 50):")
for hit in filter_search_results[0]:
print(f"ID: {hit['id']}, Distance: {hit['distance']}, Text: {hit['text']}")
# 9. (可选)删除 Collection
# client.drop_collection(collection_name=collection_name)
# print(f"Collection '{collection_name}' dropped.")
通过上述介绍和示例,可以对 Milvus 的基本概念、Docker 部署和使用有一个全面的了解。要深入学习,请参考 Milvus 官方文档,其中提供了更详细的指南和高级功能。