Appearance
集群部署
概述
Milvus 的分布式架构采用存算分离设计,将协调节点、工作节点、存储层解耦,便于各自独立扩展。当单机版无法满足数据规模或可用性要求时,就需要部署分布式集群。
Milvus 分布式架构
┌─────────────────────────────────────┐
│ 客户端 / SDK │
└─────────────────┬───────────────────┘
│ gRPC
┌────────▼────────┐
│ Proxy │ (无状态,可水平扩展)
└────────┬────────┘
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ RootCoord │ │ DataCoord │ │QueryCoord │ 协调节点(控制面)
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘ IndexCoord 同列
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ QueryNode│ │ DataNode │ │ IndexNode│ 工作节点(数据面)
└─────┬────┘ └─────┬────┘ └─────┬────┘
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ MinIO │ │ etcd │ │ Pulsar/Kafka│ 存储层
│ (对象存储) │ │ (元数据) │ │ (消息队列) │
└───────────┘ └───────────┘ └───────────┘何时用集群
| 场景 | 单机版是否够用 | 说明 |
|---|---|---|
| 数据量 < 1000 万 | 单机版足够 | 单节点即可承载 |
| 数据量 > 1000 万 | 建议集群 | 需要水平分片与并行查询 |
| 需要高可用 | 必须集群 | 单机版无故障切换 |
| 高并发写入 / 查询 | 建议集群 | 工作节点可横向扩展 |
| 需要弹性扩缩容 | 必须集群 | 配合 HPA 应对流量波动 |
前置要求
| 组件 | 最低版本 | 说明 |
|---|---|---|
| Kubernetes | 1.20+ | 推荐托管 K8s(EKS / GKE / ACK) |
| Helm | 3.8+ | 部署 Milvus Chart |
| kubectl | 1.20+ | 集群操作 |
| 存储类 | – | 至少一个可用的 StorageClass(默认或自建) |
| 节点资源 | – | 每个 worker 节点至少 4 核 8G |
确认环境就绪:
bash
kubectl version --short
helm version
kubectl get storageclassHelm 部署
添加 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: 1GiMinIO / 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: truePulsar / 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: 5bash
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: 75bash
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 索引):
| 数据规模 | QueryNode | DataNode | IndexNode | 单节点 CPU/内存 | etcd 磁盘 | 对象存储 |
|---|---|---|---|---|---|---|
| 100 万 | 2 副本 | 1 副本 | 1 副本 | 2 核 / 8G | 10Gi | 50Gi |
| 1000 万 | 3 副本 | 2 副本 | 2 副本 | 4 核 / 16G | 20Gi | 200Gi |
| 1 亿 | 5 副本 | 3 副本 | 3 副本 | 8 核 / 32G | 50Gi | 2Ti |
说明:实际资源取决于向量维度、索引类型、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依赖组件高可用
| 组件 | 高可用方案 |
|---|---|
| etcd | 3 节点跨可用区部署,Raft 仲裁 |
| MinIO | distributed 模式 ≥4 副本跨可用区 |
| Pulsar / Kafka | BookKeeper / 副本机制,≥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 # msbash
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 段堆积与索引构建积压
- [ ] 升级前有可回滚的版本与备份
下一步
掌握集群部署后,你可以: