搭建企业知识库之Milvus 向量数据库

好的,我们来深入了解一下 Milvus 向量数据库,并结合你的 Windows 环境,给出详细的安装步骤。


一、Milvus 是什么?为什么需要它?

Milvus 是一款开源的、专门为高维向量数据设计的云原生数据库。简单说,它就是为了解决"在海量非结构化数据(文本、图像、音视频)中快速找到相似内容"这个问题而生的。

1.1 Milvus 的核心价值

在 RAG 系统中,Milvus 扮演着记忆中枢的角色:

环节 作用 Milvus 的贡献
文档入库 将企业文档切块、向量化 存储向量 + 原始文本片段
用户提问 将问题向量化 在 Milvus 中检索相似向量
生成答案 将检索到的内容交给大模型 提供准确、可溯源的上下文

1.2 Milvus 的典型应用场景

  • 检索增强生成(RAG):为大模型提供外部知识库,让回答更准确、更实时
  • 推荐系统:基于用户行为向量,实时匹配最相似的商品或内容
  • 异常检测:将交易、日志转化为向量,快速发现离群点(潜在欺诈)
  • 多模态搜索:支持用文本搜图片、用图片搜图片等

二、Milvus 核心概念详解

要熟练使用 Milvus,需要先理解它的几个核心概念:

2.1 基本概念

概念 类比关系型数据库 说明
Collection(集合) 表(Table) 存储向量数据的逻辑容器,需定义 Schema
Partition(分区) 分区表 可按业务、时间拆分数据,便于隔离和查询优化
Segment(段) 数据文件 数据实际存储的物理单元,分为 Growing(增量)和 Sealed(历史)
Entity(实体) 行(Row) 一条记录,包含向量字段和标量字段
Index(索引) 索引 加速向量检索的数据结构,如 IVF、HNSW

2.2 Schema 设计要点

创建 Collection 时,需定义两类字段:

python 复制代码
from pymilvus import FieldSchema, CollectionSchema, DataType

fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),  # 主键
    FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=768),  # 向量字段,必须
    FieldSchema(name="title", dtype=DataType.VARCHAR, max_length=200),  # 标量字段
    FieldSchema(name="content", dtype=DataType.VARCHAR, max_length=2000),
    FieldSchema(name="create_time", dtype=DataType.INT64)  # 可用于时间过滤
]

2.3 一致性级别

Milvus 提供 4 种一致性级别,可根据场景权衡性能与一致性:

级别 特点 适用场景
Strong 读写强一致,性能开销高 金融交易、实时数据更新
Bounded 有限时间窗口内保证一致 推荐系统、日志分析
Session 会话内读写一致 交互式查询、用户会话
Eventually 最终一致性,性能最优 离线批量处理、非实时分析

三、Milvus 架构解析

Milvus 采用存算分离的四层架构,实现了高可扩展性:
#mermaid-svg-Dc4pFtziyOTce9VA{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Dc4pFtziyOTce9VA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Dc4pFtziyOTce9VA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Dc4pFtziyOTce9VA .error-icon{fill:#552222;}#mermaid-svg-Dc4pFtziyOTce9VA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Dc4pFtziyOTce9VA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Dc4pFtziyOTce9VA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Dc4pFtziyOTce9VA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Dc4pFtziyOTce9VA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Dc4pFtziyOTce9VA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Dc4pFtziyOTce9VA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Dc4pFtziyOTce9VA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Dc4pFtziyOTce9VA .marker.cross{stroke:#333333;}#mermaid-svg-Dc4pFtziyOTce9VA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Dc4pFtziyOTce9VA p{margin:0;}#mermaid-svg-Dc4pFtziyOTce9VA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Dc4pFtziyOTce9VA .cluster-label text{fill:#333;}#mermaid-svg-Dc4pFtziyOTce9VA .cluster-label span{color:#333;}#mermaid-svg-Dc4pFtziyOTce9VA .cluster-label span p{background-color:transparent;}#mermaid-svg-Dc4pFtziyOTce9VA .label text,#mermaid-svg-Dc4pFtziyOTce9VA span{fill:#333;color:#333;}#mermaid-svg-Dc4pFtziyOTce9VA .node rect,#mermaid-svg-Dc4pFtziyOTce9VA .node circle,#mermaid-svg-Dc4pFtziyOTce9VA .node ellipse,#mermaid-svg-Dc4pFtziyOTce9VA .node polygon,#mermaid-svg-Dc4pFtziyOTce9VA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Dc4pFtziyOTce9VA .rough-node .label text,#mermaid-svg-Dc4pFtziyOTce9VA .node .label text,#mermaid-svg-Dc4pFtziyOTce9VA .image-shape .label,#mermaid-svg-Dc4pFtziyOTce9VA .icon-shape .label{text-anchor:middle;}#mermaid-svg-Dc4pFtziyOTce9VA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Dc4pFtziyOTce9VA .rough-node .label,#mermaid-svg-Dc4pFtziyOTce9VA .node .label,#mermaid-svg-Dc4pFtziyOTce9VA .image-shape .label,#mermaid-svg-Dc4pFtziyOTce9VA .icon-shape .label{text-align:center;}#mermaid-svg-Dc4pFtziyOTce9VA .node.clickable{cursor:pointer;}#mermaid-svg-Dc4pFtziyOTce9VA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Dc4pFtziyOTce9VA .arrowheadPath{fill:#333333;}#mermaid-svg-Dc4pFtziyOTce9VA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Dc4pFtziyOTce9VA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Dc4pFtziyOTce9VA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Dc4pFtziyOTce9VA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Dc4pFtziyOTce9VA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Dc4pFtziyOTce9VA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Dc4pFtziyOTce9VA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Dc4pFtziyOTce9VA .cluster text{fill:#333;}#mermaid-svg-Dc4pFtziyOTce9VA .cluster span{color:#333;}#mermaid-svg-Dc4pFtziyOTce9VA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Dc4pFtziyOTce9VA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Dc4pFtziyOTce9VA rect.text{fill:none;stroke-width:0;}#mermaid-svg-Dc4pFtziyOTce9VA .icon-shape,#mermaid-svg-Dc4pFtziyOTce9VA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Dc4pFtziyOTce9VA .icon-shape p,#mermaid-svg-Dc4pFtziyOTce9VA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Dc4pFtziyOTce9VA .icon-shape .label rect,#mermaid-svg-Dc4pFtziyOTce9VA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Dc4pFtziyOTce9VA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Dc4pFtziyOTce9VA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Dc4pFtziyOTce9VA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 存储层
工作节点
协调服务
访问层
Proxy 节点

(无状态网关)
Coordinator 服务

(控制平面)
Query Node

(查询节点)
Data Node

(数据节点)
Index Node

(索引节点)
元数据存储

etcd
日志存储

Kafka/Pulsar
对象存储

MinIO/S3
Client

3.1 各层职责

层级 组件 核心职责
访问层 Proxy 客户端入口,请求路由、结果聚合、负载均衡
协调层 Coordinator 集群控制平面:元数据管理、任务调度、节点协调
工作层 QueryNode 执行查询,加载历史数据(Sealed Segment)
DataNode 数据写入、日志订阅、数据持久化
IndexNode 异步构建索引
存储层 MetaStore (etcd) 存储元数据(集合 schema、节点状态)
LogStore (Kafka) 存储 WAL 日志,保证数据 durability
ObjectStore (MinIO/S3) 存储向量数据、索引文件

3.2 核心设计优势

  • 无状态节点:Proxy、QueryNode、DataNode 均可水平扩展
  • 计算存储分离:各层可独立扩缩容,资源利用率高
  • 异步索引构建:数据写入与索引构建解耦,不阻塞写入

四、索引类型与选型指南

向量索引是 Milvus 实现高性能检索的关键。

4.1 主流索引对比

索引类型 原理 召回率 查询延迟 内存占用 适用数据规模
FLAT 暴力全量扫描 100% 高(秒级) < 100 万
IVF_FLAT 倒排分区 + 精确向量 可调(90%-99%) 中(毫秒级) 100 万 - 1 亿
IVF_PQ IVF + 乘积量化压缩 中高(85%-95%) 千万 - 亿级
HNSW 层次化近邻图 高(95%-99%) 低(亚毫秒) > 1 亿
DISKANN 磁盘优化索引 中高(90%-95%) 中高 极低 超大规模离线

4.2 选型建议

  • 小规模(<100 万):FLAT 足够,简单可靠
  • 中大规模(百万-千万):IVF_FLAT,平衡性能与资源
  • 超大规模(亿级+):HNSW(内存足够)或 IVF_PQ(内存受限)
  • 内存有限:IVF_PQ 或 DISKANN

五、Windows 上安装 Milvus(Docker 方式)

在 Windows 上部署 Milvus,最推荐的方式是 Docker。下面是最新(2026年)的详细安装步骤。

5.1 环境准备

步骤 1:启用 WSL 2 和 Hyper-V

管理员身份运行 PowerShell,执行:

powershell 复制代码
# 启用 WSL
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

# 启用虚拟机平台
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

# 重启电脑
Restart-Computer

重启后,设置 WSL 2 为默认版本:

powershell 复制代码
wsl --set-default-version 2

步骤 2:安装 Docker Desktop

  1. 访问 Docker 官网 下载 Docker Desktop for Windows
  2. 安装时勾选 "Use WSL 2 instead of Hyper-V"(推荐)
  3. 安装完成后重启,启动 Docker Desktop
  4. 验证安装:
powershell 复制代码
docker --version
docker-compose --version

5.2 下载并启动 Milvus

步骤 1:创建 Milvus 工作目录

powershell 复制代码
# 创建目录(可自定义)
mkdir C:\milvus
cd C:\milvus

# 创建子文件夹(用于数据持久化)
mkdir conf, db, logs, volumes, wal

步骤 2:下载 Docker Compose 文件

访问 Milvus 官方发布页,选择最新稳定版(如 v2.4.6),下载 milvus-standalone-docker-compose.yml

或者直接用 PowerShell 下载:

powershell 复制代码
# 下载 v2.4.6 版本的 compose 文件
Invoke-WebRequest -Uri "https://github.com/milvus-io/milvus/releases/download/v2.4.6/milvus-standalone-docker-compose.yml" -OutFile "docker-compose.yml"

步骤 3:启动 Milvus

powershell 复制代码
# 在 C:\milvus 目录下执行
docker-compose up -d

首次启动会拉取镜像,可能需要几分钟,取决于网络。

步骤 4:验证启动状态

powershell 复制代码
# 查看容器状态
docker-compose ps

# 应该看到三个容器:milvus-standalone、milvus-minio、milvus-etcd
# 状态均为 "Up"

验证端口:

powershell 复制代码
# 查看 Milvus 端口映射
docker port milvus-standalone 19530/tcp
# 应输出类似:0.0.0.0:19530

5.3 安装图形化管理工具 Attu(可选但推荐)

Attu 是 Milvus 的官方 GUI 工具,方便可视化操作。

步骤 1:下载 Attu

访问 Attu 发布页,下载 Windows 版本(.exe 安装包)。

步骤 2:安装并连接

  1. 双击安装,默认下一步
  2. 启动 Attu,连接信息:
    • Host : 127.0.0.1
    • Port : 19530
    • Name(可选): 随意
  3. 点击 Connect

连接成功后,即可在 Web 界面中管理 Collections、查看数据、执行查询。

5.4 验证安装:Python 快速测试

步骤 1:安装 PyMilvus

powershell 复制代码
pip install pymilvus

步骤 2:测试连接与基本操作

创建 test_milvus.py

python 复制代码
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType, utility

# 1. 连接 Milvus
connections.connect(host='127.0.0.1', port='19530')
print("连接成功!")

# 2. 创建 Collection
fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),
    FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=128)
]
schema = CollectionSchema(fields)
collection = Collection(name="test_collection", schema=schema)
print(f"Collection '{collection.name}' 创建成功")

# 3. 插入数据
import random
import numpy as np

vectors = [[random.random() for _ in range(128)] for _ in range(100)]
ids = list(range(100))
collection.insert([ids, vectors])
print("插入 100 条数据成功")

# 4. 创建索引
index_params = {
    "metric_type": "L2",
    "index_type": "IVF_FLAT",
    "params": {"nlist": 128}
}
collection.create_index(field_name="embedding", index_params=index_params)
print("索引创建成功")

# 5. 加载并搜索
collection.load()
search_vectors = [[random.random() for _ in range(128)]]
results = collection.search(
    data=search_vectors,
    anns_field="embedding",
    param={"metric_type": "L2", "params": {"nprobe": 10}},
    limit=5
)
print("搜索结果:", results[0].ids)

# 6. 清理
collection.drop()
print("测试完成,已清理")

运行:

powershell 复制代码
python test_milvus.py

如果看到"连接成功"且没有报错,说明 Milvus 已正常运转。


六、在 RAG 系统中集成 Milvus

结合你之前的搭建,在 RAG 系统中使用 Milvus 的基本流程:

6.1 文档入库

python 复制代码
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import OllamaEmbeddings
from pymilvus import Collection, connections

# 1. 连接 Milvus
connections.connect(host='127.0.0.1', port='19530')

# 2. 创建 Collection(如果不存在)
# ...(同上节 Schema 定义)

# 3. 读取文档、切分
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = text_splitter.split_documents(documents)

# 4. 向量化
embeddings = OllamaEmbeddings(model="nomic-embed-text")
vectors = [embeddings.embed_query(chunk.page_content) for chunk in chunks]

# 5. 写入 Milvus
collection = Collection("knowledge_base")
collection.insert([ids, vectors, texts, metadatas])

6.2 查询检索

python 复制代码
# 1. 问题向量化
query_vector = embeddings.embed_query(user_question)

# 2. 在 Milvus 中搜索
collection.load()
results = collection.search(
    data=[query_vector],
    anns_field="embedding",
    param={"metric_type": "IP", "params": {"nprobe": 10}},
    limit=5,
    output_fields=["text", "source"]
)

# 3. 取出检索到的文本片段
retrieved_docs = [hit.entity.get('text') for hit in results[0]]

总结

Milvus 作为专业的向量数据库,具备以下核心优势,非常适合你的企业知识库需求:

维度 Milvus 的优势
性能 亿级向量毫秒级检索,支持 GPU 加速
扩展性 存算分离架构,水平扩展无压力
企业级 支持 RBAC 权限、多租户、监控告警
生态 与 LangChain、Ollama、Spark 等无缝集成
部署灵活 支持本地、云、混合部署,Windows 上可用 Docker 快速搭建

按照上述步骤在 Windows 上完成 Docker 部署后,你就可以将 Milvus 作为知识库的向量存储引擎,与之前的 Ollama + OpenClaw-cn 组成完整的 RAG 系统了。如果在安装过程中遇到具体问题,欢迎随时提问。

相关推荐
czhc11400756631 小时前
2026-08-24 博客:几个让你少踩坑的概念
数据库
ACP广源盛139246256732 小时前
Qwen3.8‑2.4T 开源落地@ACP#国产 Serdes 长距离视频传输芯片 GSV5800 在私有化 AI 服务中的价值与应用场景
大数据·数据库·人工智能·嵌入式硬件·矩阵·开源·音视频
oradh2 小时前
Oracle RMAN备份脚本、RMAN还原恢复测试、RMAN常用语句
数据库·oracle·rman备份脚本·rman还原恢复测试·rman常用语句
汽车仪器仪表相关领域2 小时前
ZDT‑I伺服电机测试系统:四象限动态加载
大数据·数据库·分布式·功能测试·汽车·压力测试·可用性测试
云贝教育-郑老师2 小时前
Oracle 块清除(Block Cleanout):commit 之后,数据块里的“战场“谁来打扫?
数据库·学习·oracle
gs801402 小时前
Java 响应式编程详解:从 Flux、Mono 到 Spring WebFlux 技术生态
数据库·oracle
一只旭宝3 小时前
预约系统版本2(pyhton+flask可视化版本)
服务器·数据库·c++·笔记·python·flask
__zRainy__3 小时前
Node系列 · ORM:mysql 驱动程序
数据库·后端·mysql·node.js·orm
程序员夏洛3 小时前
MySQL 中如果发生死锁应该如何解决?
数据库·mysql