Skip to content

集群部署

概述

Milvus 的分布式架构采用存算分离设计,将协调节点、工作节点、存储层解耦,便于各自独立扩展。当单机版无法满足数据规模或可用性要求时,就需要部署分布式集群。

Milvus 分布式架构

              ┌─────────────────────────────────────┐
              │           客户端 / SDK               │
              └─────────────────┬───────────────────┘
                                │ gRPC
                       ┌────────▼────────┐
                       │     Proxy       │  (无状态,可水平扩展)
                       └────────┬────────┘
            ┌───────────────────┼───────────────────┐
            ▼                   ▼                   ▼
     ┌────────────┐     ┌────────────┐      ┌────────────┐
     │ RootCoord  │     │ DataCoord  │      │QueryCoord  │   协调节点(控制面)
     └─────┬──────┘     └─────┬──────┘      └─────┬──────┘   IndexCoord 同列
           │                  │                   │
           ▼                  ▼                   ▼
     ┌──────────┐      ┌──────────┐        ┌──────────┐
     │ QueryNode│      │ DataNode │        │ IndexNode│       工作节点(数据面)
     └─────┬────┘      └─────┬────┘        └─────┬────┘
           │                 │                   │
           ▼                 ▼                   ▼
     ┌───────────┐    ┌───────────┐      ┌───────────┐
     │   MinIO   │    │   etcd    │      │ Pulsar/Kafka│     存储层
     │ (对象存储) │    │ (元数据)   │      │  (消息队列) │
     └───────────┘    └───────────┘      └───────────┘

何时用集群

场景单机版是否够用说明
数据量 < 1000 万单机版足够单节点即可承载
数据量 > 1000 万建议集群需要水平分片与并行查询
需要高可用必须集群单机版无故障切换
高并发写入 / 查询建议集群工作节点可横向扩展
需要弹性扩缩容必须集群配合 HPA 应对流量波动

前置要求

组件最低版本说明
Kubernetes1.20+推荐托管 K8s(EKS / GKE / ACK)
Helm3.8+部署 Milvus Chart
kubectl1.20+集群操作
存储类至少一个可用的 StorageClass(默认或自建)
节点资源每个 worker 节点至少 4 核 8G

确认环境就绪:

bash
kubectl version --short
helm version
kubectl get storageclass

Helm 部署

添加 Milvus Helm 仓库

bash
helm repo add milvus https://zilliztech.github.io/milvus-helm/
helm repo update

自定义 values.yaml

下面是一份生产可用的精简 values.yaml,重点配置工作节点副本数与资源:

yaml
# values.yaml
cluster:
  enabled: true       # 启用分布式模式

# Proxy:无状态,按 QPS 横向扩展
proxy:
  replicas: 2
  resources:
    requests:
      cpu: "1"
      memory: 2Gi
    limits:
      cpu: "2"
      memory: 4Gi

# QueryNode:承载搜索,按并发与数据量扩展
queryNode:
  replicas: 3
  resources:
    requests:
      cpu: "2"
      memory: 8Gi
    limits:
      cpu: "4"
      memory: 16Gi

# DataNode:承载写入与刷盘
dataNode:
  replicas: 2
  resources:
    requests:
      cpu: "1"
      memory: 4Gi
    limits:
      cpu: "2"
      memory: 8Gi

# IndexNode:承载索引构建,CPU 密集型
indexNode:
  replicas: 2
  resources:
    requests:
      cpu: "2"
      memory: 4Gi
    limits:
      cpu: "4"
      memory: 8Gi

# 协调节点:控制面,单副本即可,生产建议 2 副本
rootCoord:
  replicas: 2
dataCoord:
  replicas: 2
queryCoord:
  replicas: 2
indexCoord:
  replicas: 2

安装命令

bash
# 创建命名空间
kubectl create namespace milvus

# 安装 Milvus 集群(使用自定义 values)
helm install milvus milvus/milvus \
  -f values.yaml \
  -n milvus \
  --version 4.2.0     # 对应 Milvus 2.4.x 的 chart

# 查看部署进度
kubectl get pods -n milvus -w

验证部署

所有 Pod 进入 Running 且 Ready 后,验证服务:

bash
# 1. Pod 状态
kubectl get pods -n milvus

# 2. Service
kubectl get svc -n milvus

# 3. 端口转发本地访问
kubectl port-forward service/milvus 19530:19530 -n milvus

# 4. SDK 连接验证
python -c "from pymilvus import connections, utility; connections.connect(host='localhost', port='19530'); print(utility.get_server_version())"

组件详解

组件职责推荐副本数是否有状态
RootCoord全局元数据管理、DDL 协调2(主备)有状态
DataCoord段管理、分配 segment ID、compaction 调度2(主备)有状态
QueryCoord段到 QueryNode 的分配与负载均衡2(主备)有状态
IndexCoord索引任务调度2(主备)有状态
Proxy接入客户端请求、路由、结果聚合≥2(按 QPS)无状态
QueryNode执行向量搜索与标量查询≥3(按数据量)无状态
DataNode订阅消息队列、写入段、刷盘≥2(按写入)无状态
IndexNode构建向量索引≥2(按任务)无状态

协调节点(*Coord)采用主备模式,同一时刻仅主节点工作,故副本数 ≥2 即可保证高可用;工作节点(*Node)为无状态,副本数按负载水平扩展。

存储配置

Milvus 依赖三类存储,全部在 values.yaml 中配置。

etcd(元数据)

存储 Collection Schema、段元信息等,要求低延迟:

yaml
etcd:
  replicaCount: 3           # 生产建议 3 副本,保证仲裁
  persistence:
    enabled: true
    size: 20Gi
    storageClass: "fast-ssd"
  resources:
    requests:
      cpu: "0.5"
      memory: 1Gi

MinIO / S3(对象存储)

存储段数据文件、索引文件。生产环境可直接用云厂商 S3:

yaml
# 方式 1:内置 MinIO
minio:
  mode: distributed
  replicas: 4               # 分布式模式至少 4 副本
  persistence:
    enabled: true
    size: 500Gi
    storageClass: "fast-ssd"

# 方式 2:外部 S3(推荐生产使用)
externalS3:
  enabled: true
  host: "s3.us-east-1.amazonaws.com"
  port: "443"
  accessKey: "<YOUR_ACCESS_KEY>"
  secretKey: "<YOUR_SECRET_KEY>"
  bucketName: "milvus-prod"
  useSSL: true

Pulsar / Kafka(消息队列)

解耦写入与下游处理,保证数据可靠投递:

yaml
# 方式 1:内置 Pulsar
pulsar:
  enabled: true
  broker:
    replicaCount: 2

# 方式 2:外部 Kafka(资源占用更低)
externalKafka:
  enabled: true
  brokerList: "kafka-1:9092,kafka-2:9092,kafka-3:9092"

扩缩容

手动扩缩容

通过 helm upgrade 修改副本数。例如把 QueryNode 从 3 扩到 5:

yaml
# values-scale.yaml
queryNode:
  replicas: 5
bash
helm upgrade milvus milvus/milvus -f values.yaml -f values-scale.yaml -n milvus

# 观察 Pod 扩容
kubectl get pods -n milvus -l app.kubernetes.io/component=querynode

缩容同理,把 replicas 调小即可。QueryCoord 会自动把缩容节点上的段迁移到其他节点,迁移完成后再下线 Pod。

HPA 自动扩缩容

为 QueryNode 配置基于 CPU 和内存的 HPA:

yaml
# hpa-querynode.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: milvus-querynode-hpa
  namespace: milvus
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: milvus-querynode
  minReplicas: 3
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 75
bash
kubectl apply -f hpa-querynode.yaml
kubectl get hpa -n milvus

扩容后数据 Rebalance

扩容完成后,QueryCoord 默认会自动触发负载均衡。可通过 ConfigMap 确认开关:

yaml
# queryCoord 配置
queryCoord:
  autoBalance: true         # 自动均衡
  balanceIntervalSeconds: 60

手动检查均衡情况:

python
from pymilvus import connections, utility
connections.connect(host="localhost", port="19530")
info = utility.get_query_segment_info("article_search")
for seg in info:
    print(f"segment {seg.segment_id} -> node {seg.node_id}, rows={seg.num_rows}")

资源规划

按数据规模给出的推荐配置(基于 128 维向量、HNSW 索引):

数据规模QueryNodeDataNodeIndexNode单节点 CPU/内存etcd 磁盘对象存储
100 万2 副本1 副本1 副本2 核 / 8G10Gi50Gi
1000 万3 副本2 副本2 副本4 核 / 16G20Gi200Gi
1 亿5 副本3 副本3 副本8 核 / 32G50Gi2Ti

说明:实际资源取决于向量维度、索引类型、QPS 与召回率要求,建议先以表中配置为基线压测后调整。

高可用

多副本部署

  • 工作节点(QueryNode / DataNode / IndexNode)多副本,单 Pod 故障由 K8s 自动重建
  • 协调节点(*Coord)主备模式,主节点故障自动切换
  • Proxy 多副本前置负载均衡(Service / Ingress)

跨可用区

yaml
# 让工作节点跨可用区调度
queryNode:
  replicas: 6
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app.kubernetes.io/component: querynode
            topologyKey: topology.kubernetes.io/zone

依赖组件高可用

组件高可用方案
etcd3 节点跨可用区部署,Raft 仲裁
MinIOdistributed 模式 ≥4 副本跨可用区
Pulsar / KafkaBookKeeper / 副本机制,≥3 broker
K8s 控制面托管 K8s 默认多 master

升级

滚动升级

bash
# 更新 chart 仓库
helm repo update

# 查看可升级版本
helm search repo milvus/milvus --versions

# 执行升级(保留自定义 values)
helm upgrade milvus milvus/milvus -f values.yaml -n milvus --version 4.2.1

# 观察滚动更新进度
kubectl get pods -n milvus -w

回滚

bash
# 查看历史版本
helm history milvus -n milvus

# 回滚到上一个 revision
helm rollback milvus 1 -n milvus

版本兼容性注意

  • 跨大版本升级(如 2.3 → 2.4)需先阅读官方 Release Notes,可能涉及元数据迁移
  • 滚动升级期间会有短暂的搜索延迟抖动,建议在低峰期进行
  • 客户端 SDK 版本应与服务端保持同一次版本(如服务端 2.4.x,SDK 用 2.4.x)
  • 升级前务必先备份 etcd 与对象存储,详见 数据备份与恢复

配置优化

通过 ConfigMap 调整 milvus.yaml 关键参数:

yaml
# milvus-configmap.yaml 片段
extraConfigFiles:
  user.yaml: |+
    # QueryNode 查询缓存
    queryNode:
      cacheSize: 8192          # 查询缓存大小 (MB),越大命中率越高
      segment:
        smallProportion: 0.5   # 小段阈值

    # DataNode 段密封策略
    dataNode:
      segment:
        maxSize: 512           # 段最大大小 (MB)
        sealProportion: 0.25   # growing 段密封比例

    # QueryCoord 负载均衡
    queryCoord:
      autoBalance: true
      balanceIntervalSeconds: 60

    # Proxy 超时
    proxy:
      timeTickInterval: 200    # ms
bash
kubectl apply -f milvus-configmap.yaml -n milvus
# 滚动重启使配置生效
kubectl rollout restart deployment -n milvus -l app.kubernetes.io/instance=milvus
参数作用调优建议
queryNode.cacheSize查询节点缓存数据量大时调大,提升命中率
dataNode.segment.maxSize段最大尺寸大段利于搜索、不利于更新
dataNode.segment.sealProportion段密封比例调小可加快落盘,调大可减少段数量
queryCoord.autoBalance自动负载均衡生产保持开启
indexNode.scheduler.buildParallel并行构建索引数CPU 充足时调大

生产环境检查清单

部署前

  • [ ] K8s 集群版本 ≥ 1.20,节点资源满足规划
  • [ ] StorageClass 可用,磁盘类型为 SSD
  • [ ] etcd / MinIO / 消息队列高可用部署
  • [ ] values.yaml 中资源 requests/limits 已合理设置

部署后

  • [ ] 所有 Pod Running,无 CrashLoopBackOff
  • [ ] 监控(Prometheus + Grafana)已接入,详见 监控与运维
  • [ ] 日志采集已配置
  • [ ] HPA 已就绪,告警规则已生效
  • [ ] 已完成一次压测,验证 SLA

运维中

  • [ ] 定期备份 etcd 与对象存储
  • [ ] 监控 QueryNode 内存使用率,预留 20% 余量
  • [ ] 关注 growing 段堆积与索引构建积压
  • [ ] 升级前有可回滚的版本与备份

下一步

掌握集群部署后,你可以:

  1. 学习监控与运维,保障集群稳定运行
  2. 了解性能优化,榨干集群性能
  3. 掌握数据备份与恢复,防范数据丢失