深度分享|为什么说 Zilliz Cloud 不只是把 Milvus 搬到云上
Milvus 在开源社区取得成功之后,大约从 2022 年开始,我们就在思考下一个问题:如何把 Milvus 做成一款真正的云上产品,让更多用户能够直接以服务的方式使用它。
当时摆在我们面前的,有两条路线。
第一条路线,是做一个“Milvus on XX Cloud”:尽可能保留开源 Milvus 的原有架构,将它部署、托管和运维在云上。
第二条路线,是保留与 Milvus 一致的接口、数据模型和用户习惯,但针对云环境重新设计底层架构,升级用户体验。
我们最终选择了后者。
原因在于,开源软件和云服务面对的是两类不同的问题。
作为开源系统,Milvus 必须运行在各种各样的基础设施和资源环境中。它不能假设自己一定掌握底层资源,也不能假设用户使用的是某一种固定的计算、存储或网络形态。因此,开源 Milvus 的设计首先强调广泛适用性:在尽可能多的部署环境中找到公约数,保证系统能够稳定运行。
云服务则不同。
云平台掌握底层资源池,能够进行统一的资源调度,也能够对计算、存储、网络和任务执行进行更精细的控制。它需要回答的不是“如何适应尽可能多的资源环境”,而是“在一个确定的资源模型下,怎样获得更优的性能、弹性、稳定性和成本效率”。
一旦开始利用资源池化、弹性调度、故障迁移、多租户隔离和按需计费等云上能力,许多原有的架构假设就必须随之改变。换句话说,真正的云产品不能只是把开源系统原封不动地搬到 Kubernetes 上,再在外面包一层控制台。
恰好在过去几个月,Zilliz Cloud 管控产品设计完成了一次比较大的架构调整。
借这个机会,我们可以把时间线拉长一点,回顾一下从 2023 年到现在,我们在构建 Zilliz Cloud 过程中的一些思考。
把 Milvus 托管到云上,难点远不止拉起一个服务
如果只是部署一个单体数据库,例如 MySQL 或 Redis,云上托管的核心问题通常比较简单:创建进程、挂载存储、暴露网络、做监控和运维即可。
但 Milvus 不一样。
Milvus 本身是由一组微服务构成的分布式系统。用户看到的是一个数据库 endpoint,但控制面看到的是一组组件、依赖和 K8s 资源。
它内部有负责分布式协调的 Coordinator 组件,有负责流式数据处理的 StreamingNode,有负责查询和批数据处理的 QueryNode,也有负责流量入口的 Proxy。除此之外,还需要运行时配置、ConfigMap、Pod Monitor、HPA,以及对象存储、消息队列、Index node 等外部依赖。
但是在云上,一个云上 Milvus 实例(也就是Zilliz Coud)由 Proxy、QueryNode、DataNode、MixCoord,以及 2.6 之后的 StreamingNode 等组件组成。实例背后还依赖对象存储、消息系统,以及云上池化的 Index Pool。
以IndexNode 为例,在开源版本,需要用户根据需求自主搭建;但是云上,它很早就被池化,抽象为无状态的 Index Pool。客户写入或导入数据后,索引构建由池化服务统一完成。
这意味着,想要真正把 Milvus 托管到云上,至少要解决五类问题。
第一,如何用云上的资源把 Milvus 的多个组件正确编排起来。每个组件需要多少 CPU、内存和磁盘,Proxy 如何根据流量通过 HPA 扩缩容,Pod Monitor 如何覆盖各个组件,这些都不是简单的部署问题。
第二,如何管理复杂的配置。云上实例的配置不是一份固定 Helm values。它既包括 Milvus 运行参数,也包括 K8s 资源规格与 HPA、部署拓扑与 RG/QN-SN 渲染,以及云厂商适配。
Milvus 的配置可以分为两类:一类是编排配置,例如不同 CU、不同副本数、不同价格计划、不同隔离级别下,各组件应该如何分配资源;另一类是运行时配置,例如 Milvus YAML 中与版本、规格、索引参数、读写水位相关的配置。这些配置还会叠加云、Region、MQ 类型等差异,最终形成一个巨大的笛卡尔积。
第三,如何判断一个 实例是否真正健康。云服务不能只支持创建实例,真正高频、也最容易出问题的是在线变配、升级、重启、扩缩容。有时候,Kubernetes 里所有 Pod 都是 Running,并不代表 Milvus 可以正常服务。因为它不知道这个 QueryNode 是否已经加载完整的 sealed segment,也不知道这个 StreamingNode 是否已经接管应该负责的 WAL / streaming channel。对于 QueryNode 和 StreamingNode 这类有状态服务来说,健康至少需要满足两个条件:数据完整,网络连通。仅靠 K8s 状态是不够的。
第四,如何稳定地暴露网络。云上部署 Milvus 也就是Zilliz Cloud ,不是把 Pod 和 Service 拉起来就结束,还要设计一整套入口网络,把数据库安全、稳定地暴露给用户。Zilliz Cloud 既要支持 public domain 走公网访问,也要支持 PrivateLink 这类私网访问;中间会经过 DNS、云厂商 Load Balancer、Gateway、Kubernetes Service、EndpointSlice、NEG 或 target group,最后才落到 Proxy Pod。不同云厂商在七层代理、后端发现、路由传播、权限模型上的实现都不同,网络本身就是一套复杂系统。
第五,如何处理多云和 BYOC 的额外复杂度。SaaS 模式下,数据面部署在 Zilliz 管理的云环境里;但 BYOC 模式下,数据面部署在客户自己的 VPC 中,控制面与数据面默认网络不通,需要通过反向隧道进行操作。这会进一步放大生命周期管控的复杂度。
多云差异:网络、权限和暗知识
过去几年,为了保证客户升级、扩缩容和日常运维稳定性,在云上,我们不断把数据库的生命周期管理做得更细。比如,我们不再只依赖 Operator 和 Kubernetes 的默认滚动机制,而是把节点启动、数据加载、任务迁移、流量切换和资源下线纳入统一工作流,让每一步都可以观察、判断和介入。
再比如,我们的管控系统会按组件、Pod 和副本管理资源,并通过在线调度、独立副本边界和蓝绿升级,减少变更对线上流量的影响。这些能力让大型实例的升级和扩缩容更快,也为异常排查和回退保留了更大的安全空间。
随着管控粒度不断下沉,原有的多层资源转发和状态同步逐渐成为限制。为了缩短操作链路,更准确地控制 Deployment、Service 和 Pod,我们甚至还会直接管理底层 Kubernetes 资源,来实现极致的资源调度。
但也让多云差异更加直接地暴露出来。
过去,客户希望选择适合自己的云平台和区域,而不希望承担底层基础设施差异带来的稳定性风险。也是因此,我们通过统一抽象网络和权限能力,平台可以让实例创建、私网接入、升级和故障恢复在不同云上保持相对一致的行为。
这其中包括很多细碎的 know how,例如在 GCP 上,如果走七层代理,gRPC 后端服务必须开启 TLS。这是 GCP 特有的要求。
再比如 GCP Private Link 场景中,流量从 ALB 进入后,需要通过 NEG 发现后端 Proxy Pod。如果 Proxy Service 上没有配置对应 NEG Annotation,Private Link 就找不到真正承载服务的后端 Pod。
权限模型也存在明显差异。
AWS 上,访问 S3 通常需要在 Service Account 上配置 IAM Role;GCP 除了 Service Account 权限,还可能要求 Pod 上打特定 Label;阿里云除了 Service Account,还依赖 Namespace 上的 Pod Identity 开关;华为云又走一套 OIDC 体系。
这些差异说明,要做真正云中立的 SaaS 服务,网络和权限都需要有中间层进行抽象和沉淀。否则每次深入到具体云厂商实现时,都会遇到大量暗知识。
Proxy 零停机切流:不仅数据要完整,网络也要不断
零停机不仅要求 Milvus 数据完整,还要求网络始终连通。
Milvus Proxy 被外部网关发现,依赖 Kubernetes Service 的 Selector 绑定 Proxy Pod 的 Label。在直连迁移、升级或重启 Proxy 的过程中,如果 Service 与 Pod 的对应关系处理不当,就可能导致外部网关找不到后端节点,从而断流。
这里有两个关键风险。
第一个风险是旧 Operator 的 Reconcile。如果没有先关闭旧 CR 的管理逻辑,Operator 可能把 Service 与 Pod 的关联关系刷回去,导致网关后端发现异常。
第二个风险是长尾请求和路由同步延迟。有些客户查询可能持续几分钟,不能简单地下掉旧 Proxy。同时,EndpointSlice 的变化同步到 Gateway 也需要时间。在这段时间里,仍可能有增量请求打到旧 Pod。
因此,新的流程会观察旧 Proxy 上的 Metrics,确认没有增量请求进入后,再额外等待一段时间,让长尾请求完成,最后才下线旧 Proxy。这样才能在直连迁移、升级、重启和扩缩容过程中,尽量保证客户流量不中断。
后续还可以进一步参考社区中更优雅的 readiness 与负载均衡摘流机制,把基于时间的等待,升级为更准确的状态判断。
BYOC:反向隧道和客户网络约束
针对高合规客户需求的BYOC 场景下,复杂度更高。
因为客户的数据面和 Milvus 部署在客户自己的 VPC 中,Zilliz Cloud 控制面默认无法直接访问。产品形态上,客户 VPC 内会部署一个数据面 Agent,由 Agent 反向连接到 Zilliz Cloud,建立反向隧道。管控侧不能像 SaaS 一样主动直连客户环境,而必须通过反向隧道代理操作。
此外,部分客户还有更强的网络隔离要求。例如有客户要求一个实例独占一个网关,以便给不同实例配置不同网络安全组。这与 SaaS 中一个 Region 共享一组 Envoy Gateway 的模式不同,需要为客户单独设计网络形态,并将部分逻辑下沉到 Milvus Pod 中。
这些经验也说明,BYOC 不是简单地把 SaaS 数据面部署到客户 VPC。它需要在控制链路、网络访问、权限模型、网关隔离等方面做专门设计。
尾声
一直以来,能够在云上运行 Milvus,和能够在多云、多租户和复杂企业环境中,稳定、精细、低成本地运营 Milvus,都是两件难度指数完全不同的事情。
本文只是分析其中一小部分我们的经验与认知,更多内容,我们会在系列内容之二,《Zilliz Cloud 精细管控升级的三年深度复盘》一文中,进行深度分享。







