news 2026/8/28 7:24:25

数据不搬家,也能做检索:Milvus的“湖原生”架构革命

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据不搬家,也能做检索:Milvus的“湖原生”架构革命

数据不搬家,也能做检索:Milvus的“湖原生”架构革命

——深度剖析Milvus的云原生架构、索引引擎与从2.x到3.0的存储范式跃迁

一句话概括:Milvus不是又一个向量数据库,而是一套以“存储与计算分离”为骨架、以“湖原生检索”为最新范式跃迁、以“分层微服务”为运行时的开源向量数据库操作系统——让百亿级向量检索从“先搬家再查询”的传统模式,变成“数据留在原地、索引就地构建”的零拷贝检索体系。

2019年,当Milvus在GitHub上第一次开源时,它解决的是一个很朴素的问题:如何在百万级向量上做快速的相似性搜索?

彼时,Faiss和HNSW已经在学术界证明了ANN(近似最近邻)搜索的可行性,但把它们包装成一个可扩展、可运维的数据库系统,仍然是空白。

六年后的2026年7月29日,Milvus 3.0正式发布。这一次,它要解决的问题变成了:当你的向量数据已经躺在数据湖里(Parquet、Lance、Iceberg),能不能不搬家就直接建索引、做检索?

看起来很简单,对吧?把向量往数据库里一插,就能搜了。

但是——当你的Embedding已经存在S3上的Parquet文件里,当你的数据治理要求“数据不能出湖”,当你的团队不想维护第二份在线数据副本,传统向量数据库的“先导入再检索”范式还够用吗?

Milvus 3.0给出的答案是:External Collections(外部集合)——直接在对象存储上的数据文件上构建索引,零拷贝、零迁移,让数据湖真正变得可检索。

本文将从架构演进、索引引擎、存储范式和工程实践四个维度,深度剖析Milvus的技术实现——它不是一次性的版本升级,而是一场从“向量数据库”到“向量数据湖基座(Vector Lakebase)”的范式革命

一、整体架构与设计哲学:从“微服务”到“湖原生”

1.1 架构总览:四层分离,各司其职

Milvus的架构设计遵循“存储与计算分离、控制平面与数据平面分离、云原生弹性扩展”三大核心原则。整体架构自上而下分为四层:

┌─────────────────────────────────────────────────────────────┐ │ 接入层(Access Layer) │ │ Proxy节点(无状态网关、负载均衡) │ ├─────────────────────────────────────────────────────────────┤ │ 协调层(Coordinator Layer) │ │ RootCoord / DataCoord / QueryCoord / IndexCoord │ │ (集群大脑:拓扑管理、任务调度、一致性) │ ├─────────────────────────────────────────────────────────────┤ │ 执行层(Execution Layer) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │Streaming │ │ Query │ │ Data │ │ Index │ │ │ │ Node │ │ Node │ │ Node │ │ Node │ │ │ │(实时流) │ │(历史查询)│ │(写入持久化)│ │(索引构建)│ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ 存储层(Storage Layer) │ │ 元数据(etcd) + 日志(Pulsar/Kafka) + 对象存储(S3/MinIO)│ └─────────────────────────────────────────────────────────────┘

接入层由一组无状态的Proxy节点组成,提供统一的API接口(Python/Java/Go/Node.js SDK及RESTful API),负责请求验证、负载均衡和结果聚合。

协调层是集群的“大脑”,包含RootCoord(元数据管理)、DataCoord(数据调度)、QueryCoord(查询调度)和IndexCoord(索引调度)四个协调器。集群中同一时刻仅有一个活跃的Coordinator节点(通过Raft协议实现主从切换)。

执行层是计算核心,包含三类工作节点:

  • Data Node:负责数据插入、删除和持久化,将数据从内存缓冲区刷入对象存储
  • Query Node:负责执行搜索和查询操作,从对象存储加载Segment到内存
  • Index Node:负责为Sealed Segment构建索引

存储层由三部分组成:etcd存储元数据、Pulsar/Kafka作为消息队列(WAL)、S3/MinIO作为主要数据存储。

1.2 设计哲学的两次跃迁

第一次跃迁(2.x时代):存储与计算分离

Milvus 2.0重构为云原生架构,所有组件均为无状态组件。这种设计的核心收益在于:存储和计算可以独立扩展——数据量大了就扩存储节点,查询量大了就扩Query Node。

第二次跃迁(3.0时代):湖原生(Lake-Native)

Milvus 3.0最大的架构变革,是打破了“数据必须先导入向量数据库才能建立索引和提供检索”的传统范式。向量数据可以继续存放在对象存储上的开放格式(Parquet、Lance、Iceberg、Vortex)中,由Milvus负责就地构建索引、执行检索。

1.3 版本演进:从2019到2026

版本发布时间关键变化
Milvus 1.02020年首个开源版本,支持CPU/GPU向量检索
Milvus 2.02021年云原生重构,存储与计算分离,所有组件无状态化
Milvus 2.32023年HNSW索引优化,C++实现工程级优化
Milvus 2.42024年高可用架构完善
Milvus 2.52025年内置BM25全文搜索,稀疏向量支持
Milvus 2.62026年初AISAQ磁盘索引、RaBitQ、三层存储降本85%
Milvus 3.02026年7月29日湖原生架构、External Collections、Loon存储引擎

数据来源:Milvus官方发布说明及GitHub Releases

二、核心抽象与数据模型:Collection、Segment与Chunk

2.1 数据模型的三层抽象

Milvus的数据模型采用三层抽象:

层级概念说明
Collection集合类似于关系型数据库中的“表”,是数据的逻辑组织单元
Partition分区Collection内的数据分区,支持按时间等维度划分
Segment数据存储的最小物理单元,分为Growing Segment和Sealed Segment

2.2 Segment的生命周期:从“Growing”到“Sealed”

一个Milvus数据单元的完整旅程

用户插入数据 → Proxy → 消息队列(Pulsar/Kafka) ↓ Data Node消费消息 → 写入Growing Segment(内存缓冲区) ↓ Segment达到阈值(默认122MB)→ Sealed(封存) ↓ Data Node将Chunk刷入对象存储(S3/MinIO) ↓ Index Node加载Segment → 构建索引 → 索引文件存回对象存储 ↓ Query Node加载索引 → 提供查询服务

逐层解读

① Proxy与消息队列:用户通过SDK发送插入请求到Proxy节点。Proxy对主键做哈希,决定发送到哪个Channel(Pulsar或Kafka Topic)。

② Growing Segment:Data Node从Channel消费数据,写入内存缓冲区——这就是Growing Segment。每个Shard只有一个Growing Segment。

③ Chunk与持久化:Segment增长过程中,每达到16MB就形成一个Chunk,推送到对象存储。每个Chunk是对象存储上的一个物理文件,每个字段有独立的文件。

④ Sealing与合并:当Segment达到122MB时被Sealed。Data Node定期将小的Sealed Segment合并成更大的Segment,最大可达1GB。

⑤ 索引构建:Index Node从对象存储加载Sealed Segment的数据,构建索引(如IVF、HNSW),然后将索引文件存回对象存储。

⑥ 查询服务:Query Node按QueryCoord调度,从对象存储加载Segment数据(向量、标量、索引文件)到内存或本地SSD缓存。

设计权衡(Segment大小)

该设计的收益在于:① 通过分片(Shard)和分段(Segment)充分压榨集群的并行计算能力;② Growing Segment保证“写入后立即可查”;③ Sealed Segment的不可变性简化了索引管理和并发控制。

该设计的代价在于:① 小Segment过多会影响查询性能(召回率下降);② 需要后台Compaction任务持续合并小Segment。

2.3 流批分离:Streaming Node的诞生

在经典架构中,Query Node既处理Sealed数据(历史、高吞吐),又处理Growing数据(实时、低延迟)——一个节点干了两种性质完全不同的活。

最新架构中,新增了Streaming Node,专职处理尚未Flush的Growing Segment数据:

  • 提供刚写入数据的实时搜索能力
  • 为搜索请求生成查询计划
  • 当Growing Segment达到阈值时,触发转换为Sealed Segment

同时,Index Node合并进Data Node——索引构建和Compaction都是离线批处理任务,放在同一节点可避免不必要的数据传输。

三、核心模块源码解析:索引引擎与查询执行

3.1 索引体系:从内存到磁盘的全覆盖

Milvus支持多种索引类型,覆盖不同的性能/内存/精度权衡:

索引类型原理适用场景
FLAT暴力扫描数据量小(<10万),追求100%召回率
IVF_FLAT倒排索引+聚类平衡性能与精度,通用场景
IVF_SQ8IVF + 标量量化内存受限场景
IVF_PQIVF + 乘积量化极致压缩,超大数据集
HNSW分层可导航小世界图高QPS,内存充足
DISKANN基于磁盘的ANN百亿级数据,内存极度受限
GPU_CAGRAGPU加速图索引GPU集群,追求极致吞吐
AISAQ基于SSD的磁盘索引十亿级数据,内存压缩3200倍
RaBitQ1-bit量化内存压缩至1/32,QPS提升4倍

HNSW的工程实现:Milvus 2.3版本对HNSW索引进行了C++层面的工程级优化。在鲲鹏服务器上,经过预取优化后,HNSW算法在0.99精度下不同并发的查询效率均有40%+的提升

DISKANN与AISAQ:DISKANN通过将索引放到SSD上减少内存压力。Milvus 2.6进一步引入AISAQ(由铠侠KIOXIA开发),一种受DISKANN启发的基于磁盘的向量索引。AISAQ能将十亿级搜索的内存占用压缩3200倍

RaBitQ:从Milvus 2.6开始支持,采用1-bit量化,将主索引压缩至原内存的1/32,叠加SQ8精排后整体内存占比仅28%,QPS提升4倍,召回率保持95%左右

设计权衡(索引选择)

该设计的收益在于:丰富的索引类型让用户可以根据数据规模、硬件配置和性能要求灵活选择。

该设计的代价在于:索引选型复杂——不同索引的参数(nlist、M、efConstruction等)需要针对具体场景调优。

3.2 查询执行流程:从Proxy到Segcore

一次搜索请求在Milvus中的完整执行路径:

客户端(Python/Java/Go SDK)→ gRPC/REST请求 ↓ 【Proxy】请求验证 → 生成查询计划 → 分发到各Query Node ↓ 【Query Node】ShardDelegator协调 → 并行执行 ├── Growing Segment(Streaming Node处理) └── Sealed Segment(Query Node从缓存/对象存储加载) ↓ 【Segcore(C++核心引擎)】执行查询计划 ├── 标量过滤(Visitor模式遍历表达式树) ├── 向量检索(ANN索引搜索) └── 结果合并与TopK排序 ↓ 【Proxy】聚合各节点结果 → 返回客户端

Segcore的执行机制:Milvus使用Visitor模式在Segment上执行查询计划。底层通过milvus::exec::Task管理查询的生命周期。查询执行涉及创建QueryContext来持有Segment元数据和查询参数。

标量过滤的优化:Milvus采用列式向量化的方式执行标量过滤表达式——一次处理一批数据,而非逐行处理。

3.3 索引引擎拆解:三层填充与16倍内存取舍

Milvus的索引引擎在设计上做了精妙的内存取舍:

  • 三层填充策略:索引构建过程中,通过三层填充优化内存使用和构建速度
  • 编译期分流:将不同索引类型的逻辑在编译期分离,避免运行时分支开销
  • 16倍内存取舍:在索引构建速度和内存占用之间做了明确的权衡——用更多内存换取更快的构建速度,或将内存压到极致但接受更长的构建时间

四、核心执行流程与运行时机制

4.1 写入链路:从内存到对象存储的完整旅程

Insert请求 → Proxy(主键哈希)→ Pulsar/Kafka(WAL) ↓ Data Node消费 → Growing Segment(内存缓冲) ↓(每16MB) Chunk → 对象存储(S3/MinIO) ↓(达到122MB) Seal Segment → 元数据更新(etcd) ↓ Index Node → 加载Segment → 构建索引 → 索引文件存入对象存储 ↓ Query Node → 加载索引 → 提供服务

你可能会担心:Data Node还没刷盘时节点宕机了怎么办?

别担心,WAL(Write-Ahead Log)机制保证了数据安全。所有插入请求先写入Pulsar/Kafka,Data Node从日志中消费并写入Growing Segment。即使Data Node宕机,数据仍在消息队列中,重启后可继续消费。

4.2 查询链路:Growing与Sealed的协同

查询请求到达后,ShardDelegator负责协调:

  1. Growing数据:由Streaming Node处理,保证“写入后立即可查”
  2. Sealed数据:由Query Node从缓存或对象存储加载

两种数据源的结果在Query Node层合并,统一返回给客户端。

4.3 一致性模型:时间戳与MVCC

Milvus通过TSO(Timestamp Oracle)分配全局唯一时间戳,保证事务一致性。查询时,系统基于时间戳读取特定版本的数据——类似数据库的MVCC机制。

时间旅行(Time Travel):用户可以通过指定时间戳,查询历史某个时刻的数据状态。

五、存储引擎的范式革命:从2.x到3.0

5.1 2.x时代:散落的Binlog

在Milvus 2.x中,存储模型是逐binlog文件的方式——每个Segment的每个字段对应多个binlog文件,散落在对象存储中。

这种模型的问题在于:

  • 元数据膨胀:每个binlog都需要在etcd中记录元数据
  • 读取放大:查询一个Segment需要打开大量小文件
  • Schema演进困难:增加或删除字段需要重建整个Collection

5.2 3.0时代:Manifest表 + Loon存储引擎

Milvus 3.0的存储层经历了一次范式级别的重写——从逐binlog文件模型,转向了类似Apache Iceberg的manifest表格式

新的存储引擎名为Loon,核心设计围绕三个要素展开:

  • 混合文件格式:将向量数据、标量数据和索引组织在统一的文件格式中
  • 行ID对齐:保证向量和标量在物理存储上的对齐,加速混合查询
  • Manifest:定义数据集的版本化状态,支持Schema演进和时间旅行

Loon的收益

  • 降低读取放大:随机点查不再需要打开大量小文件
  • 支持Schema演进:在线添加、回填和删除列成为可能
  • 零拷贝外部数据访问:External Collection直接读取湖上数据

5.3 External Collections:数据不搬家,也能建索引

External Collection是Milvus 3.0最核心的新功能:

# 直接在S3上的Parquet文件上定义Collectionclient.create_collection(collection_name="external_vectors",# 外部数据源:S3上的Parquet文件external_source={"format":"parquet","location":"s3://my-bucket/embeddings/"},schema=schema)# 然后就像普通Collection一样使用client.search(collection_name="external_vectors",...)

核心机制

  1. 零拷贝:数据文件不移动,Milvus直接读取对象存储上的文件
  2. 就地索引:在外部数据上直接构建向量索引、BM25倒排索引、JSON索引和标量索引
  3. 增量更新:当外部数据集更新后,Milvus读取对应的Storage Manifest,仅对新数据分片构建索引
  4. 只读:External Collections是只读的,适合治理要求“数据不能出湖”的场景

六、工程化实践:从部署到生产

6.1 部署模式与资源规划

Milvus支持两种部署模式:

模式适用场景组件
Standalone开发测试、小规模生产单进程包含所有功能
Distributed大规模生产、高并发各组件独立部署,可横向扩展

核心依赖

  • 元数据存储:etcd
  • 消息队列:Pulsar或Kafka(作为WAL)
  • 对象存储:MinIO、AWS S3、GCS、Azure Blob等

Woodpecker:Milvus 3.0引入的原生WAL服务,借鉴BookKeeper的分布式日志模型,同时结合对象存储和云网络特性进行了重新设计。在跨可用区部署、对象存储利用和成本控制方面进一步优化,性能比传统Kafka方案快5.8倍

6.2 性能优化策略

① 索引选型优化

数据规模推荐索引参数建议
< 100万HNSWM=16, efConstruction=200
100万–1000万IVF_FLATnlist=4096, nprobe=16
1000万–1亿IVF_SQ8 / IVF_PQnlist=16384, 根据精度需求
> 1亿DISKANN / AISAQ / RaBitQ根据硬件配置

② 分段大小调优

默认Segment大小为122MB,合并后最大1GB。小Segment数量过多会影响查询性能——Compaction后台任务会持续合并小Segment、清理删除数据。

③ 缓存策略

Query Node从对象存储加载Segment到内存或本地SSD缓存。合理配置缓存大小可以显著降低查询延迟。

④ 资源隔离

通过PartitionKey隔离,可在同一Collection中实现不同业务的数据隔离,提升性能。

6.3 调试与可观测性

Milvus提供了多层次的观测能力:

  • Attu:官方GUI管理工具,可视化查看Collection、Segment状态
  • Metrics:通过Prometheus暴露各项性能指标
  • 日志:各组件独立日志,支持日志级别动态调整

6.4 常见工程陷阱与解决方案

陷阱1:小Segment爆炸

大量小Segment会导致查询时打开过多文件,召回率下降。

解决方案:调整Data Node的合并策略,定期执行Compaction。生产环境建议监控Segment数量,设置合理的合并阈值。

陷阱2:索引构建资源竞争

Index Node构建索引时会消耗大量CPU和内存,可能影响查询性能。

解决方案:在Distributed部署中,将Index Node独立部署,与Query Node隔离资源。

陷阱3:消息队列积压

Pulsar/Kafka消费速度跟不上写入速度时,会导致Growing Segment积压。

解决方案:监控消息队列的Lag,适当增加Data Node数量或调整Segment刷盘阈值。

七、总结与展望

7.1 关键版本里程碑

时间版本意义
2019年Milvus开源首个开源向量数据库项目
2021年Milvus 2.0云原生重构,存储与计算分离
2025年Milvus 2.5内置BM25全文搜索,混合检索成为标配
2026年初Milvus 2.6AISAQ磁盘索引、RaBitQ、三层存储降本85%
2026年7月29日Milvus 3.0湖原生架构、External Collections、Loon存储引擎

7.2 核心设计哲学提炼

Milvus的演进可以用三句话概括:

  1. “存储与计算分离是地基,不是选项”——从2.0开始,Milvus就将无状态化作为架构的基石,让存储和计算可以独立扩展

  2. “索引不是终点,检索才是”——从FLAT到HNSW到DISKANN到AISAQ到RaBitQ,每一次索引创新都在追问同一个问题:“如何在更少的硬件上做更快的检索?”

  3. “数据在哪,检索就该在哪”——Milvus 3.0的湖原生架构,把“数据不搬家也能建索引”从理想变成了现实

7.3 核心架构亮点速览

亮点说明效果
四层分离架构接入/协调/执行/存储四层独立各层可独立扩展,高可用
流批分离Streaming Node专职处理实时数据写入后立即可查,延迟稳定
索引全覆盖从内存到磁盘、从CPU到GPU覆盖从百万到百亿级所有场景
RaBitQ量化1-bit量化压缩至1/32QPS提升4倍,召回率95%
Loon存储引擎Manifest表格式+混合文件Schema演进、零拷贝外部访问
External Collection数据湖就地建索引无需第二份副本,零拷贝检索

7.4 对开发者的启示

Milvus的故事告诉我们:向量数据库的竞争,正在从“谁更快”变成“谁更省”和“谁更灵活”。

2019年,大家关心的是“百万级向量能不能搜”。2023年,大家关心的是“十亿级向量能不能搜”。2026年,问题变成了“数据已经在湖里了,能不能不搬家就搜?”

这种“优化跑步机”不会停止。随着AI应用从“演示级”走向“生产级”,数据规模从百万走向百亿,向量数据库的架构必须持续演进。

对于开发者,这意味着:

  • 选型时关注架构演进方向——云原生是底线,湖原生是趋势
  • 部署时关注存储成本——对象存储比本地盘便宜一个数量级,能走S3就走S3
  • 索引选型要结合数据规模——百万级和亿级的索引策略完全不同
  • 关注3.0的External Collections——如果你的数据已经在数据湖里,这可能是最优解

最后,Milvus从2019年的一个向量检索工具,到2026年的湖原生向量数据湖基座——六年时间,它不仅回答了“怎么搜得快”,更在回答“怎么搜得省、搜得灵活”。而答案,正写在每一行开源代码和每一次架构重构里。

本文数据来源:Milvus官方文档(milvus.io)、GitHub Releases(github.com/milvus-io/milvus)、Milvus官方博客(blog.milvus.io)、DeepWiki及社区技术文章。所有版本号、功能特性及性能数据均基于公开可验证的官方资料。

如您所在的企业正面临向量检索、RAG系统构建或AI数据基础设施的相关需求,欢迎进一步沟通。我们可提供针对贵企业具体场景的定制化方案和现场调研服务。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 7:24:21

详解spring cloud的RestTemplate

RestTemplate 详解RestTemplate 是 Spring 提供的同步 HTTP 客户端&#xff0c;Spring Cloud 早期用来做微服务之间的服务调用&#xff0c;发送 HTTP 请求&#xff08;Get/Post/Put/Delete&#xff09;。⚠️注意&#xff1a;现在微服务开发优先用 OpenFeign&#xff1b;RestTe…

作者头像 李华
网站建设 2026/8/28 7:23:26

腾讯混元HyASR 3.0 preview:语音识别如何攻克方言与噪音难题

如果你的工作里经常要处理录音转写&#xff0c;大概会遇到这样的场景&#xff1a;一段十几分钟的会议录音&#xff0c;A是北方人&#xff0c;B说粤语&#xff0c;C偶尔蹦几个英文术语&#xff0c;背景里还有空调声和键盘声。丢给市面上的ASR工具&#xff0c;结果是普通话部分基…

作者头像 李华
网站建设 2026/8/28 7:22:45

springboot社区团购管理系统73456-计算机课程设计、毕业设计

前言 ✨ 博主介绍&#xff1a;一线全栈工程师&#xff0c;毕设实战引路人。技术栈覆盖Java、Python、C#、PHP、Node.js及UniApp跨端开发&#xff0c;擅长多语言项目落地与架构设计。持续分享毕设源码、开题报告、技术选型心得与职场踩坑经验。用工程化思维写代码&#xff0c;帮…

作者头像 李华
网站建设 2026/8/28 7:20:07

具身智能的“终极形态”:人机融合、自动化与社会重塑

前沿技术探索&#xff1a;TVA智能体&#xff08;简称TVA&#xff09;TVA智能体&#xff08;亦称“AI智能体视觉”或“TVA视觉智能体”&#xff09;是依托Transformer架构与“因式智能体”理论构建的通用视觉技术体系。它有机融合深度强化学习&#xff08;DRL&#xff09;、卷积…

作者头像 李华