
向量库讨论里有一句老话:embedding 一更新,整库重灌。Milvus 3.0 把另一条路推到前台——数据继续躺在湖仓(Parquet / Lance / Iceberg / Vortex 等),Milvus 在外面建索引、提供检索,官方称之为 lake-native,以及 External Collection。
Zilliz / LF AI & Data 在 3.0 正式版说明里把它写成架构级更新,不只是小版本特性。我关心的不是发布会用词,而是:复制那一份“服务副本”的钱和一致性,能不能少付一点。
以前为什么总要搬一次
典型链路:
- 离线任务算出 embedding,写进对象存储或湖表
- 再 bulk load 进 Milvus / 其他向量库
- 在线服务只信向量库里的那份
问题跟着来:
- 双份存储:湖一份、向量库一份
- 漂移:湖更新了,serving 还是昨晚的
- 回填贵:模型换代或字段变更,往往整集合重建
对金融、医疗一类“数据不能随便出境/出域”的团队,第二份副本还有合规摩擦:向量库集群和湖不在同一治理边界时,审批比技术难点还烦。
图:湖里的数据可以留下,索引与检索算力往外挂

External Collection 实际承诺什么
按官方文档的口径,External Collection 大致是:
- 集合映射到湖里已有文件/表,源数据不搬进图
- 在外部数据上建向量、标量、BM25/全文、JSON 等索引
- 查询 API 尽量与原生 collection 一致
- 以 只读 + 零拷贝(相对“再吞一份原始行”而言) 为默认心态
- 用增量 refresh 对齐湖侧追加/演进;3.0 里外部字段还能喂给函数输出字段(如稀疏向量、embedding 函数),减少“先复制再加工”
它解决的是“检索计算靠过去,数据所有权仍归湖”。它不自动变成你的主事务库,也不替你解决“湖上小文件爆炸”这种老问题。
我建议的试点姿势
不要一上来把生产主索引切成 External。先挑一类负载:
- 语料本身已在 Iceberg/Parquet,日更或小时增
- 查询以召回为主,写入走湖的管线,不走向量库点写
- 能接受 refresh 延迟(秒到分钟级,看你怎么调度)
试点清单:
- 字段映射表:哪些列是向量、哪些是过滤标量、哪些只存不索
- 新鲜度 SLO:refresh 周期、失败告警、查询是否允许读到旧索引
- 失败演练:删湖分区、权限收回、schema 加列——索引是否只补丁 segment 而非整库砸掉
- 成本对照:对象存储 + 索引盘 vs 旧方案全量副本盘
查询侧把“顶层 hybrid”从应用里往引擎收一收。3.0 强化了库内排序、聚合、分面、多向量打分一类能力。以前在服务里写的“先 ANN 再 SQL 滤再自己排”,有机会收成更少的往返。能下推就下推,但要在 explain / 慢查询里确认,别假设一定更快。
和“再搞一套湖仓”的区别
有人听完会说:那不就是 search engine 连 S3吗?接近,但产品边界不同。
- 你已有 embedding 与业务标量同表,想少复制
- 你要和现有 Milvus 运维、SDK、生态继续合作
- 你需要向量 + 全文 + 标量在同一查询入口
如果团队已经在用专用湖仓检索引擎,并且没有 Milvus 历史包袱,不必为了追版本强行迁。工具选择看已有管道,不看星数。
仍要自己扛的部分
- 小文件与布局:湖上千万小 Parquet,任何外部索引都会痛。先整理成合理 compaction,再让 Milvus 指过去。
- 删除语义:只读外挂时,“删除”往往是湖侧快照/分区语义,和点删 API 不是同一套直觉。
- 写入型业务:会话记忆、实时用户事件,仍更适合可写 collection 或专门在线存储。External 更像“主数据在湖的检索加速器”。
- 版本与模型:embedding 模型切换仍要有策略——新列、新索引、蓝绿 collection,湖原生不消除模型变更,只是少搬原始语料。
小结
Milvus 3.0 的 lake-native / External Collection,把向量检索从“必须再吞一份数据”里松了绑。适合语料已在开放表格式、召回为主、愿意用 refresh 换一致性的团队。先做只读试点和成本表,确认 schema 演进与失败路径,再考虑把 hybrid 排序从应用挪进引擎。副本不是耻辱,盲目双写才是。


