Milvus 向量数据库

cloud-yuan
67
2025-08-20

Milvus 向量数据库详细介绍

1. 什么是 Milvus?

Milvus 是一个开源的 向量数据库,专门为 AI 应用设计,用于高效存储、检索和分析海量向量数据。它支持:

  • 相似性搜索:通过计算向量距离(如欧氏距离、余弦相似度等)找到最相似的向量

  • 高性能:优化了大规模向量检索,支持十亿级向量毫秒级查询

  • 多种索引类型:IVF_FLAT、HNSW、ANNOY、SCANN 等

  • 混合查询:支持向量 + 标量数据的联合过滤查询

2. 核心组件

组件

作用

协调节点

管理查询请求和资源分配

查询节点

执行向量相似性搜索

数据节点

管理数据的持久化和压缩

索引节点

负责向量索引的构建

对象存储

通常使用 MinIO/S3 存储实际向量数据

元数据存储

使用 etcd/MySQL 存储元信息

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:

使用说明

  1. 启动所有服务

     docker-compose up -d
  2. 访问服务

    • Milvus:通过 localhost:19530 连接

    • Attu 界面:浏览器打开 http://localhost:8000

      • 如果设置了用户名/密码,使用 admin/admin123 登录

      • 连接地址填写 standalone:19530(容器内网络)或 host.docker.internal:19530(Docker 特殊域名)

  3. 数据持久化

    • 所有数据保存在 Docker volumes 中:

       docker volume ls
  4. 版本升级: 修改镜像版本号后重新启动:

     image: milvusdb/milvus:v2.5.4  # 修改版本号
     image: zilliz/attu:v2.5.4      # Attu 版本需与 Milvus 匹配

关键配置说明

  1. MinIO 配置

     environment:
       - MINIO_ACCESS_KEY=minioadmin    # 生产环境应修改
       - MINIO_SECRET_KEY=minioadmin    # 生产环境应修改
  2. Milvus 性能调优

     environment:
       - KNOWHERE_MAX_PARTITION_NUM=256  # 最大分区数
       - KNOWHERE_USE_BLAS_THRESHOLD=20  # BLAS 加速阈值
  3. Attu 安全配置

     environment:
       - ATTU_DISABLE_TELEMETRY=true  # 禁用数据统计
       - HTTPS_ENABLED=true           # 启用 HTTPS(需配置证书)

常见问题解决

  1. 连接问题

    • 如果 Attu 无法连接 Milvus,尝试将 MILVUS_URL 改为:

       environment:
         - MILVUS_URL=host.docker.internal:19530
  2. 数据清理

    docker-compose down -v  # 删除所有容器和 volumes
  3. 性能监控

    • Prometheus 监控端点:http://localhost:9091/metrics

如何使用向量数据库

使用Python调用Ollama中的BAAI/bge-m3模型进行向量处理

要使用Python调用Ollama中已部署的BAAI/bge-m3模型进行向量处理,你可以按照以下步骤操作:

前提条件

  1. 确保Ollama服务已安装并运行

  2. 已通过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]

注意事项

  1. BAAI/bge-m3模型生成的向量维度通常是1024维

  2. 确保Ollama服务有足够的内存资源运行模型

  3. 对于长文本,可能需要先进行分块处理

  4. 生产环境中建议添加错误处理和重试机制

向 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)

注意事项

  1. 数据类型匹配:确保你插入的数据类型与集合 schema 中定义的类型完全匹配

  2. 主键唯一性:主键字段的值必须是唯一的

  3. 向量维度:向量数据的维度必须与集合定义中的维度一致

  4. 刷新操作:插入后调用 flush() 可以使新数据立即可搜索,但会带来性能开销

  5. 性能考虑:大批量插入时建议关闭自动刷新 (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 管理界面验证

  1. 访问 http://localhost:3000 (Attu 默认端口)

  2. 在顶部选择目标数据库(如 ecommerce_db

  3. 查看 products 集合中的数据


常见问题解决

Q1: 报错 Database not found

  • 确认数据库已创建:SHOW DATABASES;

  • 检查拼写是否一致(区分大小写)

Q2: 字段类型不匹配

  • 首次插入时会自动推断类型,后续插入必须兼容

  • 建议预先明确定义 Schema

Q3: 如何列出所有数据库? 目前需要通过 Milvus 命令行或 Attu 界面查看,Python SDK 暂未直接提供此接口。