Milvus 向量数据库的详细执行流程:从数据入库到查询召回

发布时间:2026/7/7 2:33:48
Milvus 向量数据库的详细执行流程:从数据入库到查询召回 在 RAG 系统里Milvus 通常承担“长期记忆库”的角色。文档被切分、向量化之后不是简单地塞进普通数据库而是存入 Milvus 这样的向量数据库中。等用户提问时系统再把问题也转成向量到 Milvus 里找语义最接近的内容片段最后交给大模型生成答案。可以把 Milvus 的核心执行流程理解成两个阶段数据写入与索引构建阶段查询检索与结果召回阶段这两个阶段一前一后分别解决“知识怎么存进去”和“问题来了怎么找出来”。第一阶段数据写入与索引构建这一阶段发生在构建知识库时。比如我们有一批 PDF、Word、Markdown 或网页文档需要把它们处理后存进 Milvus。1. 原始文档进入系统最开始系统拿到的是普通文本资料例如课程文档、产品手册、论文、业务知识库等。这些文档通常不能直接整体丢进向量数据库因为一篇文档太长语义粒度太粗后续检索也不精准。所以第一步通常是加载文档清洗无用内容按段落、标题、长度进行切分得到多个较小的文本块也就是 chunk一个 chunk 可以理解成 RAG 系统里的最小知识单元。2. 文本被转换成向量Milvus 本身不负责理解文本语义它负责存储和检索向量。所以在入库前需要先用 Embedding 模型把每个 chunk 转成向量。常见做法是生成两类向量稠密向量 dense vector表达整体语义相似度比如“苹果手机”和“iPhone”虽然字面不同但语义接近。稀疏向量 sparse vector更关注关键词匹配比如专有名词、编号、术语、代码等。如果使用 BGE-M3 这类模型就可以同时生成稠密向量和稀疏向量。这样后续既能做语义检索也能做关键词增强检索。3. 设计 Collection 和 Schema在 Milvus 中数据不是随便存的而是存进一个 Collection。Collection 类似传统数据库里的表。一个典型的 RAG Collection 可能包含这些字段id主键vector稠密向量字段sparse_vector稀疏向量字段text原始 chunk 文本metadata来源、页码、文件名、章节等元信息这样设计的好处是Milvus 不只返回“哪个向量相似”还可以把对应的原文片段和来源信息一起返回。4. 创建索引向量数据如果只靠全量扫描数据量一大就会很慢。所以 Milvus 会为向量字段建立索引。例如稠密向量可以使用HNSW、IVF_FLAT等 ANN 索引稀疏向量可以使用SPARSE_INVERTED_INDEX相似度计算方式可以选择COSINE、IP、L2索引的作用类似“高速导航地图”。没有索引时查询需要挨个比较有索引后Milvus 可以快速缩小搜索范围找到最可能相似的一批结果。5. 客户端发起 insert 请求当 schema 和索引参数准备好后应用程序通过 Milvus SDK 调用insert把数据写入 Milvus。写入的数据通常是一组字典结构例如{ vector: dense_vector, sparse_vector: sparse_vector, text: chunk_text, metadata: { source: sample.pdf, page: 12 } }这些数据会先进入 Milvus 的访问层。6. Proxy 接收并转发请求Milvus 集群中客户端不是直接操作底层节点而是先访问 Proxy。Proxy 可以理解成 Milvus 的入口网关。它负责接收请求、校验请求并根据请求类型转发给后面的服务。对于 insert 这类写入请求Proxy 会把它转发到负责写入链路的节点。7. 写入 WAL保证数据不丢Milvus 写数据时不会只写内存。它会先写入 WAL也就是 Write-Ahead Log预写日志。WAL 的意义是即使系统中途宕机只要日志还在数据就有机会恢复。它相当于给写入过程加了一层保险。在 Milvus 的架构里WAL 通常依赖消息队列系统例如 Kafka 或 Pulsar。8. 数据进入 Growing Segment刚写进来的数据会先形成 Growing Segment。Growing Segment 可以理解成“正在增长的数据段”。这部分数据还没有完全落盘也可能还没完成索引构建但它已经可以参与查询。这点对 RAG 很重要因为用户刚上传一份文档后通常希望马上就能检索到而不是等很久。9. Flush 后形成 Sealed Segment当 Growing Segment 达到一定条件后Milvus 会执行 flush把数据持久化到对象存储中例如 MinIO 或 S3。这时数据段会从 Growing Segment 变成 Sealed Segment。Sealed Segment 的意思是这个数据段已经封存不再继续追加新数据。后续 Milvus 可以围绕它做索引构建、压缩和优化。10. Data Node 异步构建索引和压缩数据落盘后Data Node 会在后台继续处理这些 Sealed Segment。它主要做两件事Indexing给向量数据构建 ANN 索引例如 HNSW。Compaction把零散的小 segment 合并减少碎片提高检索效率。这个过程是异步的。也就是说写入请求不需要一直等到所有索引都建完才返回。Milvus 会先保证数据写入再慢慢优化查询性能。到这里第一阶段完成文档已经被切分、向量化、写入 Milvus并逐步完成索引优化。第二阶段查询检索与结果召回第二阶段发生在用户提问时。比如用户问“Milvus 是如何保证写入后马上可查的”系统要从 Milvus 里找出最相关的 chunk再交给大模型生成答案。1. 用户问题先被向量化用户输入的是自然语言Milvus 不能直接拿这句话做向量相似度计算。因此系统会先使用同一个 Embedding 模型把问题转成查询向量。如果入库时用了稠密向量和稀疏向量查询时也最好生成两类向量dense query vectorsparse query vector这样可以保持入库和查询的向量空间一致。2. 客户端发起 search 或 hybrid_search如果只查一个向量字段可以使用普通search。如果同时查稠密向量和稀疏向量可以使用hybrid_search。混合检索通常会构造两个请求一个请求查vector字段做语义相似度搜索一个请求查sparse_vector字段做关键词相关性搜索然后再用 RRF 等排序方法把两路结果融合。3. Proxy 接收查询请求查询请求同样先到 Proxy。Proxy 会判断这是 DQL 查询请求然后把请求路由给 Query Node。Query Node 是 Milvus 中真正负责执行向量检索的节点。4. Query Node 搜索历史数据对于已经落盘、已经构建好索引的 Sealed SegmentQuery Node 会加载对应的索引和数据。这部分检索速度很快因为可以利用 HNSW、倒排索引等结构做 ANN 近似最近邻搜索。简单说就是 Milvus 不会傻乎乎地把所有向量都拿出来逐个算而是通过索引快速找到最可能相似的候选结果。5. Query Node 同时搜索实时数据Milvus 的一个关键设计是它不仅查已经落盘的历史数据还会查刚写入不久、可能还没完成索引构建的实时数据。这部分数据可能还在 Growing Segment 中。由于还没建立完整索引Milvus 可能会对这部分数据做相对直接的扫描计算。这样做的好处是刚插入的数据也能立刻被查到。这就是 Milvus 支持“写入即可查”的核心原因。6. 合并历史结果和实时结果Query Node 会把两类结果合并来自 Sealed Segment 的索引检索结果来自 Growing Segment 的实时检索结果合并后Milvus 会按照相似度分数重新排序取出 TopK。如果是混合检索还会进一步融合稠密向量结果稀疏向量结果常见融合方式是 RRF。它不简单依赖某一路分数而是根据多个召回列表里的排名综合计算得到更稳的最终排序。7. 应用过滤条件在实际 RAG 系统里检索通常不只是“找最相似的文本”。还可能附带过滤条件比如只查某个文件只查某个用户上传的知识库只查某个时间范围只查 metadata 中某个 source 的内容Milvus 支持标量字段和 JSON 字段过滤所以可以先过滤再检索或者在检索过程中结合过滤条件。8. 返回 TopK 结果最终 Milvus 会把 TopK 结果返回给客户端。每条结果通常包含命中的id相似度分数原始文本text元信息metadata应用程序拿到这些结果后会把文本片段拼接成上下文再交给大模型生成最终回答。总结Milvus 的执行流程可以简单概括为入库阶段文档 → 切分 → 向量化 → 写入 WAL → 形成 Segment → 落盘 → 建索引查询阶段问题 → 向量化 → Proxy 路由 → Query Node 检索历史数据和实时数据 → 合并排序 → 返回 TopK它真正解决的是两个问题第一海量高维向量如何高效存储和索引。第二用户查询时如何在毫秒级到秒级时间内找到最相关的文本。所以在 RAG 系统中Milvus 不是简单的“向量仓库”而是连接文档知识和大模型回答能力的核心检索引擎。