用K8S部署Milvus服务
以下是对 Milvus 的简要介绍及基于 Kubernetes 的详细部署 YAML 代码,包含高可用架构、持久化存储及关键组件配置。
Milvus 简介
Milvus 是一款开源的分布式向量数据库,专为海量向量数据的相似性搜索和 AI 应用设计,核心特性包括:
- 多向量索引支持:IVF、HNSW、Annoy 等算法。
- 水平扩展:支持动态扩缩容数据节点和查询节点。
- 云原生架构:依赖组件包括 etcd(元数据存储)、MinIO/S3(对象存储)、Pulsar/Kafka(消息队列)。
- 多语言 SDK:Python、Java、Go 等。
部署架构
- Milvus 核心服务:
- Data Node:处理数据写入和持久化。
- Query Node:处理向量搜索请求。
- Index Node:构建向量索引。
- Root Coordinator:协调集群元数据。
- Proxy:对外暴露 API 的入口。
- 依赖组件:
- etcd:存储元数据(3 节点集群)。
- MinIO:对象存储(替代生产环境的 S3)。
- Pulsar:消息队列(日志流)。
详细部署 YAML 代码
1. 创建 Namespace
apiVersion: v1
kind: Namespace
metadata:
name: milvus
2. 部署 etcd 集群(元数据存储)
# etcd StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: etcd
namespace: milvus
spec:
serviceName: etcd
replicas: 3
selector:
matchLabels:
app: etcd
template:
metadata:
labels:
app: etcd
spec:
containers:
- name: etcd
image: quay.io/coreos/etcd:v3.5.7
env:
- name: ETCD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ETCD_DATA_DIR
value: /var/lib/etcd
- name: ETCD_INITIAL_CLUSTER
value: "etcd-0=http://etcd-0.etcd:2380,etcd-1=http://etcd-1.etcd:2380,etcd-2=http://etcd-2.etcd:2380"
- name: ETCD_INITIAL_ADVERTISE_PEER_URLS
value: "http://$(POD_NAME).etcd:2380"
- name: ETCD_LISTEN_PEER_URLS
value: "http://0.0.0.0:2380"
- name: ETCD_LISTEN_CLIENT_URLS
value: "http://0.0.0.0:2379"
- name: ETCD_ADVERTISE_CLIENT_URLS
value: "http://$(POD_NAME).etcd:2379"
ports:
- containerPort: 2379
name: client
- containerPort: 2380
name: peer
volumeMounts:
- name: etcd-data
mountPath: /var/lib/etcd
volumeClaimTemplates:
- metadata:
name: etcd-data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "standard"
resources:
requests:
storage: 10Gi
---
# etcd Service
apiVersion: v1
kind: Service
metadata:
name: etcd
namespace: milvus
spec:
clusterIP: None
ports:
- port: 2379
name: client
- port: 2380
name: peer
selector:
app: etcd
3. 部署 MinIO(对象存储)
# MinIO Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: minio
namespace: milvus
spec:
replicas: 1 # 生产环境建议 4 节点分布式部署
selector:
matchLabels:
app: minio
template:
metadata:
labels:
app: minio
spec:
containers:
- name: minio
image: minio/minio:RELEASE.2023-09-04T19-57-37Z
args:
- server
- /data
env:
- name: MINIO_ROOT_USER
value: "minioadmin"
- name: MINIO_ROOT_PASSWORD
value: "minioadmin"
ports:
- containerPort: 9000
- containerPort: 9001
volumeMounts:
- name: minio-data
mountPath: /data
volumes:
- name: minio-data
persistentVolumeClaim:
claimName: minio-pvc
---
# MinIO PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: minio-pvc
namespace: milvus
spec:
accessModes:
- ReadWriteOnce
storageClassName: "standard"
resources:
requests:
storage: 50Gi
---
# MinIO Service
apiVersion: v1
kind: Service
metadata:
name: minio
namespace: milvus
spec:
ports:
- port: 9000
targetPort: 9000
- port: 9001
targetPort: 9001
selector:
app: minio
4. 部署 Milvus 核心服务
# Milvus Proxy Service (API 入口)
apiVersion: v1
kind: Service
metadata:
name: milvus-proxy
namespace: milvus
spec:
type: NodePort # 生产环境建议 LoadBalancer 或 Ingress
ports:
- port: 19530
targetPort: 19530
nodePort: 30001
selector:
app: milvus-proxy
---
# Milvus 组件 Deployment(示例:Proxy、Data Node、Query Node)
apiVersion: apps/v1
kind: Deployment
metadata:
name: milvus-proxy
namespace: milvus
spec:
replicas: 2
selector:
matchLabels:
app: milvus-proxy
template:
metadata:
labels:
app: milvus-proxy
spec:
containers:
- name: proxy
image: milvusdb/milvus:v2.3.3
command: ["milvus", "run", "proxy"]
env:
- name: ETCD_ENDPOINTS
value: "etcd-0.etcd:2379,etcd-1.etcd:2379,etcd-2.etcd:2379"
- name: MINIO_ADDRESS
value: "minio:9000"
- name: MINIO_ACCESS_KEY
value: "minioadmin"
- name: MINIO_SECRET_KEY
value: "minioadmin"
ports:
- containerPort: 19530
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
# Data Node、Query Node、Index Node 类似,需分别部署
验证部署
-
检查 Pod 状态:
kubectl get pods -n milvus -l app=milvus-proxy
-
测试 Milvus 连接:
from pymilvus import connections, Collection connections.connect(host="<K8S_NODE_IP>", port=30001) # 使用 NodePort 地址 print(connections.list_collections()) # 应返回空列表(新集群)
关键配置说明
-
高可用性:
- etcd:3 节点集群,避免元数据单点故障。
- Milvus 组件:Proxy、Data Node 等多副本部署。
-
持久化存储:
- etcd:通过 PVC 持久化元数据。
- MinIO:存储向量数据文件,生产环境建议使用分布式存储(如 Ceph 或 AWS S3)。
-
资源分配:
- Proxy:至少 2 CPU 核心和 4GB 内存。
- Data Node:根据数据量增加内存和存储。
生产环境优化建议
-
分离组件角色:
- 专用 Root Coordinator、Data Coordinator 等组件。
# 示例:Root Coordinator - name: rootcoord image: milvusdb/milvus:v2.3.3 command: ["milvus", "run", "rootcoord"]
-
监控与日志:
- 集成 Prometheus + Grafana 监控集群指标。
- 使用 EFK(Elasticsearch + Fluentd + Kibana)收集日志。
-
安全加固:
- 启用 MinIO TLS 加密。
- 配置 Milvus 身份验证(需企业版支持)。
通过以上配置,您可以在 Kubernetes 上部署一个基础的 Milvus 向量数据库集群,适用于开发测试环境。生产部署需根据负载调整副本数、存储方案及网络策略。
Milvus 作为分布式向量数据库,其核心功能(数据管理、向量搜索)依赖于 etcd 和 MinIO 等组件的协作。以下是它们的职责分工和协作流程:
1. 组件职责
组件 | 角色 | 核心功能 | 类比 |
---|---|---|---|
Milvus | 向量数据库 | 向量数据存储、索引构建、相似性搜索 | 数据库引擎(如MySQL) |
etcd | 元数据存储 | 存储集合、分片、节点状态等元信息 | 数据库的“目录系统” |
MinIO | 对象存储 | 存储原始向量数据、索引文件等大文件 | 数据库的“硬盘” |
2. 协作流程(以数据写入为例)
(1) 用户写入数据
- Proxy 接收客户端请求(如插入向量数据)。
- Proxy 将数据写入消息队列(如 Pulsar/Kafka,未在YAML中体现,但实际部署需包含)。
- Root Coordinator 通过 etcd 记录元数据(如数据对应的分片、版本信息)。
(2) Data Node 处理数据
- Data Node 消费消息队列中的数据,进行以下操作:
- 序列化:将向量数据转换为文件格式(如 Parquet)。
- 上传至 MinIO:将文件存储到 MinIO 的指定 Bucket。
- 更新元数据:通过 etcd 记录文件路径、版本等元信息。
(3) Index Node 构建索引
- Index Node 根据配置的索引类型(如 HNSW、IVF),从 MinIO 拉取数据文件。
- 构建索引后,将索引文件上传回 MinIO,并通过 etcd 记录索引元数据。
(4) Query Node 处理搜索请求
- Query Node 收到搜索请求后:
- 从 etcd 获取目标集合的元数据(如分片分布、索引类型)。
- 根据元数据定位 MinIO 中的索引文件和数据文件。
- 加载索引和数据,执行相似性搜索并返回结果。
3. 关键协作场景
(1) 元数据一致性
- etcd 作为分布式键值存储,确保所有 Milvus 节点访问的元数据一致。
- 例如:当创建新集合时,Root Coordinator 将集合的 Schema 和分片信息写入 etcd,所有节点通过监听 etcd 获知变更。
(2) 数据持久化与高可用
- MinIO 存储实际数据文件,确保即使 Milvus 节点宕机,数据仍可从对象存储恢复。
- 生产环境中,MinIO 需配置为分布式模式(多节点 + 纠删码),避免数据丢失。
(3) 故障恢复
- Data Node 宕机:
Milvus 通过 etcd 检测节点状态,自动将宕机节点的分片迁移到其他健康节点,新节点从 MinIO 拉取数据重建服务。 - etcd 集群故障:
etcd 基于 Raft 协议实现高可用,半数以上节点存活即可正常服务。若全部节点宕机,Milvus 将不可用,需优先恢复 etcd。
4. 生产环境优化建议
(1) etcd 高可用
- 部署 3/5 节点的 etcd 集群,跨可用区分布。
- 监控 etcd 性能(如写入延迟、存储空间)。
(2) MinIO 分布式部署
- 至少 4 节点 MinIO,启用纠删码(Erasure Coding)提高数据可靠性。
- 示例配置:
# MinIO 分布式部署(4节点) apiVersion: apps/v1/v1 kind: StatefulSet spec: replicas: 4 volumeClaimTemplates: - metadata: name: data spec: accessModes: [ReadWriteOnce] storageClassName: "standard" resources: requests: storage: 100Gi
(3) 分离 Milvus 组件角色
- 专用 Root Coordinator、Data Node、Query Node,避免资源竞争。
- 示例配置(YAML 片段):
# 专用 Root Coordinator - name: rootcoord image: milvusdb/milvus:v2.3.3 command: ["milvus", "run", "rootcoord"] env: - name: ETCD_ENDPOINTS value: "etcd-0.etcd:2379,etcd-1.etcd:2379,etcd-2.etcd:2379"
5. 总结
- etcd:Milvus 的“大脑”,管理元数据和集群状态。
- MinIO:Milvus 的“硬盘”,持久化存储向量和索引文件。
- 协作逻辑:
通过 etcd 维护一致性,通过 MinIO 实现数据持久化,Milvus 各组件基于两者协作完成向量数据的存储、索引和查询。
三者缺一不可,共同保障系统的可靠性、扩展性和高性能。