Milvus开源社区历经六年沉淀,从部署到迁移,我们总结出大量实战经验与精华,在此与大家分享。
核心内容:
- Milvus版本选择指南:根据实际业务需求,判断最佳部署方案
- 性能优化与数据管理:提炼用户反馈,解决开发者常见痛点
- 从Lite到Distributed:不同版本适用于不同规模与需求的向量数据库应用场景
今天查看Milvus的Star数量,已接近3.5万,达到新的里程碑。回顾过去,从0到100,从100到10,000,再到如今,时间已过去近六年。在此期间,我们发布了多个重要版本,也收获了全球更多开发者的使用与反馈。
在这段历程中,无数问题从评论区、Issue、Meetup中涌来——有技术上的Bug,有产品使用疑问,也有许多朋友纯粹的关心与支持。而在许多看似“重复”的提问背后,我们提炼出三个关键词:
- 部署
- 性能
- 数据管理
这些都是产品下一步迭代中需要持续优化的方向,也是当下许多开发者面临的困扰。今天,我们在这里做一个系统的答疑与经验分享。
01 我应该选什么版本?
部署是整个系统设计的起点。在我们的社区中,最常被提及的问题是:“我到底该选哪个版本?”是Milvus Lite这种轻量模式,还是Standalone的本地单机版本?要不要直接上Distributed做集群?Zilliz Cloud真的值得托管吗?
Lite好用,但不够“完整”;Standalone足够“自主”,但扩展性有限;Distributed强大,但代价大、可调参数多。这背后,其实是对场景的判断。于是有一项工作开始变得重要——在文档中,不再只讲特性,而是讲使用场景。
我们也第一次明确区分了:
- 小团队原型验证用Lite。在本地系统存储几百万个向量(用于原型验证),或为单元测试和CI/CD寻找嵌入式向量数据库时,可以使用Milvus Lite。需要注意的是,Milvus Lite还不具备全文搜索等高级功能,但即将推出。
- 百万至亿级生产落地用Standalone(图搜、商品检索)。如果你的系统需要为生产流量提供服务,或者你需要存储几百万到上亿个向量,你应该使用Milvus Standalone,它将Milvus的所有组件打包到一个Docker镜像中。同时还有docker compose部署的单机模式,可以将持久存储(MinIO)和元数据存储(etcd)作为单独的镜像部署。
- 上亿向量或者上千QPS场景推荐Distributed。对于任何服务于生产流量的大规模部署(比如大型知识库检索、推荐系统),可以使用Milvus Distributed。如果有些用户希望执行海量数据的离线批量处理(例如重复数据删除),即将推出的Milvus 3.0将通过向量湖来解决这一问题。
- 如果你不想配集群,就直接上Zilliz Cloud。对于希望专注于应用程序开发而无需担心DevOps的开发者来说,Zilliz Cloud可以提供全托管Milvus服务。
更进一步,部署的本质是判断:判断你当前的挑战是什么,你愿意为未来的弹性付出多大成本。
02 我需要多少内存、存储和算力?
社区里另一个最常见的问题是:“我该给Milvus分配多少内存、多少CPU?”关心这个问题的,不仅包括现有的Milvus用户,还有那些正在考虑Milvus是否适合其业务场景的用户。
但部署需要多少内存、存储空间和算力,取决于各种复杂因素的相互作用:由于使用的模型不同,向量embedding的维度也不同。有些向量索引完全存储在内存中,其他的则将数据存储到磁盘上。另外,很多索引实际存储的是embedding的压缩(量化)副本。
当然,技术上,这些问题都有解法。我们开发了一个自动估算资源的工具:https://milvus.io/tools/sizing,你只需输入向量维度、条数、索引类型和部署选项等信息,就能估算出不同类型的Milvus节点及其依赖组件所需的CPU、内存和存储空间。具体情况因人而异,建议使用自己的数据在测试环境中提前测试以验证效果。
03 我应该选择哪种向量索引?
在收到的所有提问里,“我该选哪个向量索引”也是出现频率极高的问题。我们在向量索引上深耕多年,深知要理解清楚每一个索引,对无数普通开发者而言,都是一个个难以观测、难以对比的黑箱。
但我们始终相信:“早启动 > 慢精调”。因此,Milvus提供了AutoIndex。它的初衷是为了让你在“不想选”“不知道选谁”或者“选择过程太繁琐”的时候,先让机器智能地帮你决策,把系统跑起来,好让你能先把注意力放在更关键的地方,比如数据本身有没有问题、embedding模型是否有效。有时候,“召回率低”不是索引的问题,而是模型精度就不够,或者embedding一开始就是错的。
不过,如果你想选择特定的索引类型,这里也有一些经验可供参考。通常可以把索引划分为“内存型”“磁盘型”“GPU型”,接下来我们就从这三种类型出发来聊一聊。
关于内存索引:检索速度最快,但内存成本高。常见的IVF_FLAT、HNSW等索引目前Milvus全都支持。此外,大多数索引会量化向量以减少内存使用量,但需要内存来存储额外的数据结构。其他非向量数据(标量)及其索引也会占用内存空间。
关于磁盘索引:如果我们需要处理数十亿向量,又没有海量内存的时候,可以使用DiskANN和MMap。DiskANN可以将未压缩向量+图搜索结构放在磁盘上,只在内存中维护高度压缩副本。当然,“低延迟”有前提——你需要使用NVMe硬盘(毕竟,SATA的性能会让你怀疑人生)。而MMap则是用虚拟内存机制将索引根据需要在磁盘和内存之间交换。这样,如果每次只使用一小部分数据,也能加载完整的索引,但频繁的页面交换会导致延迟过高。很多做日志回放、长尾分析的用户,反而偏爱这种“按需加载”的方式。
关于GPU索引:GPU的好处是并行、多线程、吞吐强,但缺点也很明显:调度复杂、成本更高、代码链路更难维护。Milvus支持的GPU索引由NVIDIA RAPIDS团队提供,可以在高并发场景下跑出低于CPU的延迟。但只有当你的查询量大到数百或数千个“压榨满GPU”时,才更有性价比。毕竟GPU的内存通常小于CPU RAM,运行成本也更高。
04 如何选择距离度量和embedding模型
关于距离度量,一个很有意思的现象是:很多用户在选择索引后才来问:“我用L2还是Cosine?”但其实,这件事你在训练embedding模型时就应该确定。如果你做的是文本类任务,Cosine或等价的Inner Product (IP)是最自然的选择。如果你做的是图像类任务,那L2可能更合适。换句话说,这不是“Milvus应该支持什么”的问题,而是“你在训练时就要问自己:我想让模型靠近的,是方向,还是位置?”
关于各种embedding模型参数,Zilliz在文档中也整理了一张表,可以参考:https://zilliz.com/ai-models。
既然距离度量取决于embedding模型,接下来肯定有人会问:那么怎么选embedding模型?这个问题很难给出明确的答案,因为这取决于你对性能的要求以及你处于哪个阶段。与选索引类似,embedding模型也需要在计算、存储和召回率之间权衡。在其他条件相同的情况下,输出维度较大的embedding需要更多存储空间,但召回率可能会更高。对于固定维度,较大的embedding模型通常在召回率方面优于较小的embedding模型,但代价是计算量和时间会增加。
MTEB、OpenCompass这些排行榜,确实有参考意义。但最优模型不会写在排行榜上,因为它们是跑在标准数据集上的。而实际落地的数据,常常带着噪声、行业术语、口语表达,甚至拼写错误。因此,我们一般建议:实在不知道怎么选的时候,就从一个基础模型开始,比如all-MiniLM-L6-v2。不是因为它最好,而是它“刚好好用”——维度不高、速度可控、资源友好。“我先用一个能跑的模型上线,然后用数据去佐证是否值得更换。”
05 Milvus Distributed 部署出问题怎么办
很多用户第一次部署Milvus Distributed后,最先碰到的问题,不是性能瓶颈,不是API不通,而是——系统启动不起来。或者更准确地说:系统启动了,但“不太确定运行是否健康”。这些问题很正常,因为分布式架构的本质,是复杂组件之间的协同——延迟、配置、网络、存储、索引、数据同步,任何一处微小的变化都会让系统表现出“意料之外”的行为。但很难给出一个单一的解决方案,因为每个问题似乎都与上一个问题不同。
06 如何在 Windows 上部署 Milvus?
还有一个问题,我们看到很多次:“我能不能在Windows上跑Milvus?”首先,Windows上跑Milvus不是“最优选择”,但有时候需要的并不是最优,因为现实情况可能是:本地验证更快、团队只有Windows笔电、CI环境被限制了权限……
我们相信,所有对用户加上条条框框的“最优”,都是产品与技术的偷懒,我们必须让用户在每个“我不确定能不能跑”的节点上,都能有一条“跑得通”的路径。于是我们干脆重写了“在Windows上部署Milvus”的文档,具体可以参考文档说明。
07 如何做性能与状态监控
搞定部署之后,很多人的问题就会从“怎么部署”进入“到底跑得怎么样”。但这时候另一个难题又来了:“我该怎么看(平均查询延迟、延迟分布、查询量、内存使用、磁盘存储)性能?”
因为看不到系统的每一步行为,开发者们面对系统卡顿之类的Bug,常常会不知道哪个节点在处理哪一段数据,不知道搜索为什么挂起,不知道副本同步是不是堵住了,甚至担心“不行,我是不是部署错了”。因此,Milvus 2.5提供了新的WebUI,就是为了回答这些看似“简单”、实则“非常人性化”的问题。我们希望你能像刷一张数据图表一样刷你的系统状态,而不是SSH进去grep日志。WebUI的核心目的,就是给你一种“观察”的可能性。它不一定立刻解决问题,但它至少能让你明白:“问题在哪里”,以及“它是怎么发生的”。
当然还存在一类高级用户,他们不会止步于“跑起来”,而是会继续追问:
- Milvus的段(segment)什么时候会被seal?
- 内存占用为什么会上下波动?
- 查询到底怎么跨节点路由?
为了回应这些“深度好奇者”,我们不断完善了概念文档、架构图、压缩机制说明,甚至把一些工程师内部笔记的部分也拿出来作为公开参考资料。详情可以参考这两个页面:https://milvus.io/docs/architecture_overview.md 和 https://milvus.io/docs/clustering-compaction.md。
我们将继续改进Milvus内部文档,使其更易于理解,并欢迎通过大家提出任何反馈或要求。我们相信,理解的深度,决定了能力的边界。
08 如何做迁移
得益于广大开发者的信任,越来越多的朋友开始从其他产品向Milvus迁移,或者从低版本向高版本迁移,遇到的问题包括但不限于:“我可以把Elasticsearch的数据迁过来吗?”“Milvus 2.4和2.5的数据格式能兼容吗?”“我能不能把Standalone的数据搬到Zilliz Cloud上?”
很多用户是带着旧系统、历史数据、模型版本来的,没有平滑迁移,就没有用户体验与所谓的升级。围绕这个诉求,我们提供了两个核心工具:
- VTS(Vector Transfer Service):让你能把向量数据从其他平台(Pinecone、Elasticsearch、Qdrant等)迁移进来,不需要手动重新建索引。https://github.com/zilliztech/vts
- Zilliz Cloud托管迁移服务:帮助你把原先的自托管部署,平滑过渡到云端环境,支持版本差异和断点续传。https://docs.zilliz.com/docs/migrations
借助这两个工具,我们希望任何人选择Milvus与Zilliz Cloud,都不需要放弃之前的所有积累,而是将它变成一个可以自由进出、随时切换、你始终能掌控数据流向的基础设施。
尾声
为什么我们要记录这些?因为社区的声音,是我们认识自己最真实的镜子。Milvus是大家共同努力的结果,任何一位发声的用户不仅是“用户”,也是伙伴,这是对我们的一种深度的信任,也是一种稀缺的关系。更因为Milvus的设计初衷从来不是“大而全”,而是“可对话”(我们不仅希望社区可对话,后续Milvus也将支持自然语言查询,做到产品可对话)。
我们愿意承认:它还不完美。有的文档不够清晰,有的配置不够智能,有些索引还在改进。但它有一个特质:你越用它,它越懂你。你第一次跑查询,它会试着默认帮你选索引。你想上生产,它会暴露更多参数给你控制。你迁移数据,它会尽可能兼容旧格式,降低你选择的成本与代价。它应该是那种——你用得越久,越信它的AI时代的基础设施,一个可以随时与你对话并进化的老朋友。
