资讯动态

基于Helm在Kubernetes上部署Milvus与Qdrant实战指南

发布时间:2026/10/16 7:33:33 来源:尧图企业网站定制
1. 项目概述为什么要在K8s上跑向量数据库最近在做一个知识库相关的项目需要处理海量的非结构化数据比如文档、图片的特征向量。传统的MySQL、PostgreSQL虽然在关系数据上很强但面对向量检索这种高维度、近邻搜索的场景性能和扩展性都不太够用。所以我把目标锁定在Milvus和Qdrant这两个专业的向量数据库上。既然要服务于生产环境直接裸机部署显然不是长久之计Kubernetes带来的弹性伸缩、故障自愈、资源隔离能力恰恰是这种数据密集型组件最需要的土壤。加上Helm这个包管理工具整个部署过程可以做到可重复、可追踪环境迁移也变得容易很多。这个标题看起来简单但里面涉及的细节其实不少。比如Milvus依赖的etcd、MinIO、Pulsar或者Qdrant的存储配置、副本策略如果只是在单机上docker run一下很多问题根本暴露不出来。而一旦放到K8s集群里存储类StorageClass怎么选资源限制怎么定服务怎么暴露安全配置怎么做每一步都可能成为瓶颈。这篇文章主要面向已经对Kubernetes有基础了解、正准备把向量数据库落到实际项目中的开发者或者已经在生产环境摸爬滚打过、想看看别人怎么处理这些组件间关系的运维同学。我会从整体的部署架构讲起然后分别拆解Milvus和Qdrant的具体部署步骤包括Helm Chart的选择、values文件的定制、存储和网络的配置最后还会分享一些我在实际部署中遇到的问题和排查思路。整个过程中涉及的参数和命令都是可以直接拿去用的不过生产环境的集群情况各有差异建议你在应用的时候结合自身的资源情况做调整。2. 部署方案选型为什么是Helm而不是裸YAML2.1 Helm在向量数据库部署中的优势用Kubernetes部署应用最常见的两种方式就是直接编写YAML文件或者使用Helm Charts。在部署Milvus和Qdrant这种带有很多依赖组件的系统时我更倾向于用Helm。原因很简单——这些系统涉及的资源对象太多了。以Milvus为例包含Coordinator、DataNode、QueryNode、IndexNode等多个组件每个组件又需要对应的Service、ConfigMap、StatefulSet或者Deployment。如果用裸YAML管理一方面要手动维护这些资源之间的配置关联另一方面升级版本时容易出错回滚也更麻烦。Helm把这一堆资源打包成一个Chart通过values.yaml文件统一管理配置参数。需要更新副本数改一行配置就行需要更换镜像版本也只需要改tag。更重要的是Helm支持版本化发布部署后随时可以回滚到上一个稳定版本。对于我这种经常要在不同环境之间复制部署逻辑的人来说Helm的这种可移植性非常实用。整个Chart打包好之后在开发、测试、生产环境执行几乎一样的命令只需要替换values文件里的差异部分即可。2.2 Milvus和Qdrant的架构差异对比选择Milvus还是Qdrant不是拍脑袋决定的而是要看项目需求。这两个系统虽然都做向量检索但架构设计思路差别挺大的。Milvus老版本1.x的架构偏简单但到了2.x版本直接进化成了存算分离的分布式架构。它内部拆分为多个角色RootCoord负责元数据管理和DDL操作DataCoord管理数据段Segment的写入QueryCoord和QueryNode负责查询执行IndexCoord和IndexNode负责索引构建。存储层则依赖etcd元数据存储、MinIO或者S3对象存储、Pulsar或者Kafka消息队列。这种设计的好处是横向扩展能力很强QueryNode和DataNode都可以独立扩容但带来的问题就是部署部署链路变长运维时需要关注更多组件。Qdrant则完全不同它是一个单体应用用Rust编写单二进制文件就能跑起来。存储模型借鉴了传统数据库的WAL预写日志机制数据写盘后通过Memmap内存映射实现高性能读取。虽然也支持分布式部署但架构复杂度远低于Milvus。单机的Qdrant性能出色而需要支撑亿级别向量的场景时可以通过分片和副本进行水平扩展。从部署角度来看Qdrant在Helm Chart中只有一个核心deployment对底层依赖的要求相对简单只要解决存储和网络即可。Milvus则更像一个全家桶部署前要先把etcd、MinIO这些依赖伺候好。这种架构差异在实际部署时会直接影响工作量和故障排查的复杂度。我通常的建议是如果项目规模在千万级向量以下、追求部署简洁和运维省心优先考虑Qdrant如果未来要支撑更大的数据量、需要精细控制索引构建和查询资源那么Milvus更合适。2.3 部署前的环境准备与版本选择动手部署之前有几个前置条件必须先确认好能省掉后面不少麻烦。Kubernetes集群版本是第一个要考虑的因素。我用的环境是1.24以上的版本因为新版本的K8s在存储卷、调度策略、网络策略方面都有不少改进Helm也对这些版本有更好的兼容性。集群至少要有4个节点每个节点建议配置8核16GB内存以上。Milvus那套老演员组件etcd、MinIO等对资源的要求比预想中高尤其是MinIO如果只是默认配置跑起来也许没问题但数据量一上来就会暴露IO瓶颈。Helm版本建议用3.8以上因为旧版本对仓库管理、Chart依赖的处理方式不太一样按新版本的用法操作会报错。另外要保证集群有可用的StorageClass。如果你的集群没有预先创建可以在部署前通过一个简单的PVC测试一下默认存储是否可用。我在第一次部署Milvus时就吃过亏集群里没有安装任何存储插件结果Pod一直处于ContainerCreating状态卡了将近十分钟才发现是PVC没有Provisioner。版本选择方面Milvus官方在Helm仓库中维护的Chart版本和镜像版本需要对应。不要盲目追求最新版本我目前用的Milvus版本是2.4.x对应的Chart版本在x.x.x这个区间具体在部署时可以通过命令查看。Qdrant版本更新节奏也很快我建议选一个较新的稳定版本就行没必要追最新。注意部署前务必检查集群节点的时间是否同步。etcd和Qdrant对时间偏差都挺敏感的时间不同步会导致Raft选举异常或者数据一致性校验失败。可以用chrony或者systemd-timesyncd做时间同步这事在云厂商托管的K8s环境里一般已经处理好了自建集群就得自己上心。3. 基于Helm部署Milvus向量数据库全流程3.1 添加Helm仓库与依赖组件规划Milvus的官方Helm仓库地址是托管在GitHub上的通过helm repo add命令添加即可。但在真正部署之前我先梳理了一下整个依赖链。Milvus 2.x的默认模式会依赖etcD做元数据存储MinIO做对象存储Pulsar做消息队列。这些组件如果全部通过Milvus的Helm Chart自动部署好处是省心坏处是资源占用大而且升级Milvus时这些依赖组件的版本不一定能跟着合理升级。所以我在实际环境中采用了混合模式。对于测试环境直接使用Chart内置的依赖组件一条命令全部拉起来对于生产环境我会提前部署好独立的etcd、MinIO或者使用云厂商的对象存储服务然后在Milvus的values配置中指向外部服务。这样做的好处是隔离故障域Milvus升级时不影响底层依赖存储服务的策略和备份也能独立管理。helm repo add milvus https://zilliztech.github.io/milvus-helm/ helm repo update执行完repo update之后可以通过以下命令查看可用的Chart版本helm search repo milvus --versions注意观察Milvus Chart版本和Milvus应用版本的对应关系有些Chart版本号看起来很高但对应的Milvus版本可能并不是你想要的。我一般会先用helm show values查看一下默认配置确认版本和依赖组件的默认值再动手。3.2 定制values.yaml从测试到生产的参数变化直接使用默认values部署Milvus在小规模测试环境是可行的但如果你想要更稳的生产配置有几个参数必须调整。第一个是持久化存储配置。Milvus依赖MinIO做数据持久化默认配置下MinIO会使用emptyDir一旦Pod重启数据就没了。这在生产环境是不可接受的。我需要指定一个可用的StorageClass并且为MinIO设置足够的存储容量。同样的etcd也需要持久化存储否则元数据丢失会导致整个Milvus集群不可恢复。第二个是消息队列的选择。Milvus 2.x默认使用Pulsar但Pulsar组件较重量级如果只是做功能验证可以考虑把消息队列切换到Kafka或者直接禁用消息队列。在Milvus 2.3之后的版本中引入了基于RocksDB的本地消息存储模式适合数据量不大的场景。我在测试环境中就启用了这个模式把Pulsar整个去掉了部署速度快了不少资源占用也明显下降。不过生产环境数据量较大时还是建议保留独立的消息队列。第三个是每个组件的资源限制。Milvus各个Node的默认资源requests和limits配置都比较保守在数据量上来之后容易出现OOM或者CPU节流。我在生产配置中给QueryNode和IndexNode分配了更充足的资源同时给DataNode设置了合理的磁盘吞吐要求。具体参数如下所示你可以根据集群的节点规格做调整。# values-milvus-prod.yaml etcd: replica: 3 persistence: enabled: true storageClass: nfs-client size: 20Gi resources: requests: memory: 512Mi cpu: 250m limits: memory: 1Gi cpu: 1 minio: mode: distributed persistence: enabled: true storageClass: nfs-client size: 200Gi resources: requests: memory: 2Gi cpu: 1 limits: memory: 4Gi cpu: 2 pulsar: enabled: false messageQueue: rocksmq queryNode: replicas: 2 resources: requests: memory: 2Gi cpu: 1 limits: memory: 8Gi cpu: 4 dataNode: replicas: 2 resources: requests: memory: 1Gi cpu: 1 limits: memory: 4Gi cpu: 2 indexNode: replicas: 1 resources: requests: memory: 1Gi cpu: 1 limits: memory: 4Gi cpu: 2这里我需要解释一下为什么MinIO要用distributed模式。Milvus的数据段最终都会落到对象存储里如果MinIO是单机模式一旦宕机整个Milvus的读取路径就全断了。distributed模式至少提供了一定程度的高可用数据打散到多个节点上单个节点故障不影响数据完整性。etcd的replica设置为3也是个基准要求。etcd是Raft协议实现的分布式协调服务只有凑齐奇数节点才能正常选举Leader。3个节点是生产环境的最低标准配置。如果集群节点资源紧张etcd也可以先部署1个节点但要做好etcd单点故障后Milvus集群写入元数据会失败的心理准备。3.3 部署Milvus与验证集群状态values文件准备好之后部署命令很简单。只要指定release名称、Chart名称和values文件路径即可。helm install milvus-prod milvus/milvus -f values-milvus-prod.yaml -n milvus等命令执行完成可以查看所有Pod的状态kubectl -n milvus get pods正常情况下你会在输出里看到类似这样的状态etcd-0、etcd-1、etcd-2都是Running状态minio-0到minio-3处于Ready状态milvus的各个组件也都显示为Running。如果某个Pod一直处于Pending状态通常就是PVC没有绑定成功可以用kubectl describe命令看一下具体原因绝大多数情况是StorageClass配置有问题。Pod全部跑起来之后再检查一下服务是否能正常通信kubectl -n milvus get svcMilvus默认会暴露两个服务端口一个是19530用于gRPC通信客户端SDK连接的就是这个端口另一个是9091用于Prometheus指标采集。确认服务类型是ClusterIP之后如果你要从集群外部访问还需要创建一个Ingress或者把Service改成LoadBalancer。我建议生产环境用Ingress配合TLS证书测试环境可以直接改成NodePort方便调试。kubectl -n milvus port-forward svc/milvus-prod 19530:19530执行完port-forward之后在本地通过Python客户端做一次连通性测试确认能够创建Collection并插入几条向量数据。这一步能提前暴露网络层面的问题避免在应用接入阶段才手忙脚乱。4. 基于Helm部署Qdrant向量数据库实战4.1 Qdrant Helm Chart的仓库与依赖Qdrant的Helm Chart托管在官方仓库中添加方式如下helm repo add qdrant https://qdrant.github.io/qdrant-helm helm repo update和Milvus不同Qdrant的Helm Chart结构简单很多核心就是一个Deployment加一个Service附带PVC和可选的Ingress配置。所以从学习成本角度来说Qdrant对新手非常友好。你对Kubernetes的基础理解足以应对Qdrant的部署而Milvus还需要理解分布式系统中多个角色如何协同工作。虽然Qdrant架构简单但它在分布式模式下依赖一个重要的协调机制——在Qdrant 1.x版本之后它通过Raft协议实现多个节点之间的元数据同步和数据分片调度。这意味着如果配置多个副本节点之间必须能够互相通信而且需要持久化存储来保存Raft日志和分片数据。所以虽然部署的组件少了但存储和网络配置反而更重要了。Qdrant的Helm Chart默认会创建以下资源一个StatefulSet管理Pod的有序部署和稳定网络标识一个Headless Service用于集群内节点间通信一个或者多个PVC每个副本对应一个数据卷可选的Ingress用于外部访问和Dashboard4.2 Qdrant的values定制与存储策略Qdrant的存储是它最核心的部分。它使用本地磁盘保存segment文件、WAL日志和Raft元数据不依赖外部对象存储。这就意味着PVC的IO性能直接影响查询和写入的延迟。我建议使用SSD类型的StorageClass如果集群用的是网络存储比如NFSIO延迟会明显偏高再加上并发写入时候的锁竞争性能可能跟本地盘差距很大。来看一个我实际使用的values文件已经做了必要的参数优化# values-qdrant-prod.yaml replicaCount: 3 image: repository: qdrant/qdrant tag: v1.9.0 pullPolicy: IfNotPresent config: log_level: INFO service: http_port: 6333 grpc_port: 6334 storage: performance: max_segment_size: 100 max_optimization_threads: 4 cluster: enabled: true p2p: port: 6335 persistence: accessModes: - ReadWriteOnce storageClass: local-ssd size: 100Gi resources: requests: memory: 2Gi cpu: 1 limits: memory: 8Gi cpu: 4 service: type: ClusterIP ports: - name: http port: 6333 targetPort: 6333 - name: grpc port: 6334 targetPort: 6334 ingress: enabled: true className: nginx hosts: - host: qdrant.example.local paths: - path: / pathType: Prefix tls: - secretName: qdrant-tls hosts: - qdrant.example.local几个参数的解读。replicaCount设置为3这是为了让Raft协议能正常工作。Qdrant的集群模式要求至少3个节点才能容忍单节点故障。如果只部署1个副本其实也能用但没有高可用能力数据丢失风险较高。如果只有2个副本Raft选举可能出现平票情况反而不如1个副本稳定。max_segment_size控制的是segment文件的最大大小。Qdrant在写入数据时会把向量数据切片到多个segment中每个segment内部有自己的索引结构。这个值越大segment数量越少但因为segment内的数据越多写入时的内存消耗也越高值越小segment越细碎查询时需要合并更多的结果段。对于大多数场景100这个值是均衡的不需要频繁调整。cluster.enabled设置为true表示开启分布式集群模式。这样多个Qdrant节点之间可以相互通信数据分片会自动分布在各个节点上。如果你只有一个副本这个参数可以不启用但既然要部署到K8s我建议直接开启后面扩展节点时不用再改配置。4.3 部署Qdrant和外部访问配置values文件准备好之后执行部署命令helm install qdrant-prod qdrant/qdrant -f values-qdrant-prod.yaml -n qdrant检查Pod状态kubectl -n qdrant get pods因为是StatefulSetPod名称会带有序号比如qdrant-prod-0、qdrant-prod-1、qdrant-prod-2。这三个Pod启动后需要确认它们之间能够互相通信。可以通过日志查看Raft状态kubectl -n qdrant logs qdrant-prod-0 | grep -i raft如果配置正确日志里会显示节点之间的选举和Leader建立过程。如果日志显示一直处于Candidate状态说明节点间的网络通信有问题大概率是Headless Service没有正确解析或者集群节点的安全组规则没有放通6335端口。对外访问方面我在ingress中用了一个测试域名如果你没有域名可以通过NodePort方式临时测试。Qdrant自带的Web UI也是一个非常好用的调试工具访问http://qdrant.example.local/dashboard就能看到Collections的管理界面。这个Dashboard在开发和测试阶段非常实用可以直接在界面上创建Collection、插入数据、执行向量搜索不用另外写代码就能直观地验证数据效果。5. 工具选型与细节配置存储、网络与安全5.1 StorageClass的选择对性能的影响存储是部署向量数据库时最容易忽略但影响最大的环节。Milvus通过MinIO间接访问对象存储Qdrant直接读写本地卷但底层都是通过PVC挂在物理存储上。StorageClass决定了PVC创建时使用的存储类型和参数不同存储类型的性能差距非常大。我在实际项目中用了三种不同的StorageClass做对比结果可以给你参考。第一种是NFS类型的网络存储适合小规模测试环境部署简单但延迟较高。第二种是Local SSD本地盘性能极高适合承载Qdrant的数据但不支持跨节点迁移Pod被调度到别的节点后无法自动挂载原数据。第三种是云厂商的云盘类型性能和可用性比较均衡也支持在线扩容缺点是IOPS可能受到云盘规格限制。Milvus的MinIO组件我建议使用云盘或者企业级分布式存储因为MinIO本身就是分布式存储系统它自己对底层存储的IO要求反而没那么敏感。Qdrant则强烈建议使用SSD尤其是做高并发向量搜索时随机读性能直接影响响应时间。我曾经在测试环境中用NFS跑Qdrant单条向量查询就要几十毫秒换成SSD后降到几毫秒性能提升非常明显。需要留意的是如果使用Local SSD需要配合local-path-provisioner这类存储插件来动态创建PVC否则Pod调度后可能因为节点标签不匹配而无法挂载卷。5.2 网络配置Headless Service、端口与IngressK8s集群内部通信和外部访问的设计在向量数据库部署时同样不能忽略。Milvus的Coordinator和Worker节点之间、Qdrant的多副本之间都需要稳定的网络通道。Qdrant的Headless Service是集群模式工作的基础。集群模式下每个Pod通过qdrant-prod-0.qdrant-prod-headless.qdrant.svc.cluster.local这样的DNS名称来访问其他节点。如果你只部署了ClusterIP类型的ServicePod之间的Raft通信可能走转发路径稳定性受影响。端口规划方面Milvus主要需要开放19530gRPC和9091MetricsQdrant需要开放6333HTTP、6334gRPC、6335P2P。如果你的集群启用了NetworkPolicy需要额外创建允许这些端口通信的规则。Ingress配置外部访问时需要注意路径转发规则。Qdrant的Dashboard和API都走同一端口路径匹配用Prefix方式即可。Milvus没有内置Web UI一般只需要转发19530端口或者通过客户端SDK在集群内部直接连接。安全方面只配置Ingress还不够。如果Qdrant Dashboard暴露在公网我建议至少在Ingress层增加Basic Auth或者通过TLS证书对接统一身份认证平台。Milvus本身也支持TLS但配置过程稍复杂需要在values中指定证书文件然后让各个组件都挂载同样的证书。好在一开始不用急着给内部组件之间做TLS先保证外部访问链路是加密的内部组件之间通过K8s网络隔离通常是可接受的。5.3 监控与调优Metrics、日志和资源管理部署完成只是第一步后续的监控和调优才是保证系统长期稳定运行的关键。Milvus和Qdrant都支持Prometheus指标暴露接入监控体系后可以实时观察系统的运行状态。Qdrant暴露的指标中我重点关注这几个qdrant_collection_vectors_count集合中向量数量、qdrant_segment_countsegment数量、qdrant_raft_replicasRaft副本状态、qdrant_http_responses_total请求量和延迟。通过Grafana仪表盘可以直观看到写入吞吐和查询延迟的变化趋势。Milvus的监控体系更复杂一些需要采集每个组件的指标。我在监控面板上特别关注QueryNode的CPU使用率、DataNode的磁盘IO时间、MinIO的Bucket存储量和etcd的Leader状态。如果QueryNode的CPU长时间处于高位说明查询压力较大可能需要扩容。日志方面Milvus和Qdrant都输出到stdoutK8s平台会自动收集日志。建议部署日志采集Agent比如Loki或者ELK中的Filebeat把Pod日志统一聚合。我在排查问题时用得最多的手段就是kubectl logs加grep过滤关键字日志聚合后可以快速定位跨节点的异常。调优方面有个细节很值得分享。Qdrant的Raft日志默认存储在PVC中如果长时间运行日志文件会变得很大。我在生产环境会给Qdrant的PVC额外预留20%的空间来容纳Raft日志增长。如果空间不足Raft节点会报错并停止参与选举整个集群的写入能力会中断。Milvus的etcd同样有这个风险需要监控etcd的存储空间使用率。6. 常见问题与排查技巧实录6.1 Pod一直Pending或ContainerCreating这是我在部署过程中遇到最频繁的问题。Pod处于Pending状态最大的可能是PVC无法动态创建或者节点资源不足。用kubectl describe pod查看Event信息如果报错信息包含Failed to provision volume或者Waiting for persistent volume to be created那基本就是StorageClass的问题。检查一下StorageClass是否存在、对应的Provisioner是否正常运行。自建K8s环境经常没装存储插件需要先安装一个存储系统比如Rook、Longhorn或者简单的NFS Provisioner。ContainerCreating状态通常跟镜像拉取有关。如果集群无法访问外网镜像拉取会超时。解决办法是提前把镜像导入到私有镜像仓库然后修改values中的image仓库地址。Milvus的镜像比较多我建议提前把etcd、MinIO、Milvus相关的镜像都准备好。6.2 Milvus组件之间通信失败Milvus部署成功后如果出现查询超时或者写入失败先检查各个组件之间的连接。常见的原因是etcd地址配置错误或者消息队列服务不可达。我在第一次部署Milvus时就遇到过QueryNode一直报etcd连接失败的错误后来发现是因为values文件中etcd的地址写错了把内部Service名称写成了外部IP。遇到这类问题排查思路是从底层往上找。先确认etcd能否访问再确认MinIO能否访问最后再验证Pulsar或者RocksMQ能否正常生产消费。每个组件都有对应的日志顺着日志一层一层找很快就能定位问题。6.3 Qdrant集群无法选举LeaderQdrant多副本部署后如果集群一直处于无Leader状态通常有两个原因。第一是节点之间的P2P端口默认6335没有放通可以通过在两个Pod内部互相telnet测试。第二是Headless Service解析有问题需要确认Service的clusterIP: None设置正确。还有一个容易被忽视的问题Qdrant节点之间时间不同步。Raft协议对时间戳比较敏感节点间时间偏差过大时心跳超时会导致选举频繁失败。确保所有节点的时间同步后重新启动Qdrant集群一般就能恢复。6.4 查询性能不达预期如果部署完成之后查询延迟偏高我建议先从这几个方面优化。第一个是磁盘IO类型确认是否用的是SSD存储。第二个是内存大小Qdrant对热数据的缓存要求比较高内存不足时会频繁做页面置换导致延迟上升。第三个是segment数量的控制可以通过调整max_segment_size参数让segment数量保持在一个合理范围segment过多时会增加查询合并的开销。Milvus的查询性能受索引类型影响较大。在Collection中创建索引时如果使用IVF类索引需要注意nlist参数的选择。nlist的值太小查询时会扫描过多的候选集nlist的值太大会增加内存占用。我在实践中一般根据数据规模把nlist设置在1024到4096之间具体数值可以通过实验验证。6.5 故障恢复与数据备份向量数据库的数据备份是个容易忽略的环节。Milvus因为数据分散在MinIO和etcd中备份时需要同时备份这两部分。Qdrant相对简单一些可以直接通过Snapshot API在运行状态下创建一致性快照也可以直接备份PVC下的数据目录。我在生产环境中的做法是针对Qdrant编写了一个定时任务CronJob每天凌晨通过API触发Snapshot创建然后把快照文件上传到对象存储中。一旦出现数据损坏可以从快照恢复。Milvus这边通过MinIO的版本控制功能定期备份对象存储数据同时用etcd的snapshot命令备份元数据。恢复的时候先恢复MinIO再恢复etcd最后启动Milvus组件整个过程需要按照顺序操作。7. 部署后的验证与整体体验部署工作结束后建议做一次端到端的功能验证而不是只看到Pod是Running就觉得万事大吉。先通过Python SDK分别连接Milvus和Qdrant创建测试Collection写入一批随机向量再执行一次相似度搜索确认返回结果的Top-K条记录符合预期。Milvus侧的测试代码大致长这样from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType connections.connect(aliasdefault, hostlocalhost, port19530) fields [ FieldSchema(nameid, dtypeDataType.INT64, is_primaryTrue), FieldSchema(namevector, dtypeDataType.FLOAT_VECTOR, dim128) ] schema CollectionSchema(fieldsfields) collection Collection(nametest_collection, schemaschema) collection.create_index(field_namevector, index_params{index_type: IVF_FLAT, metric_type: L2, params: {nlist: 1024}}) collection.insert([[1], [[0.5] * 128]]) collection.flush() results collection.search([[0.5] * 128], anns_fieldvector, param{nprobe: 16}, limit10) print(results)Qdrant侧的验证用REST API就能完成curl -X PUT http://localhost:6333/collections/test_collection -H Content-Type: application/json -d {vectors: {size: 128, distance: Cosine}} curl -X PUT http://localhost:6333/collections/test_collection/points -H Content-Type: application/json -d {points: [{id: 1, vector: [0.5] * 128}]} curl -X POST http://localhost:6333/collections/test_collection/points/search -H Content-Type: application/json -d {vector: [0.5] * 128, limit: 10}如果这两步都成功说明部署链路是通的。接下来可以逐步加压测试大batch写入时的表现观察是否需要调整worker线程数或者缓存参数。完成这些验证之后系统才算是真正可以交给业务方使用。这两个向量数据库在K8s上的部署方式虽然差异不小但整体思路是相通的先把依赖的存储和网络基础打牢再关注组件自身的配置细节最后通过监控和日志持续优化。实际跑下来Qdrant的部署和维护确实省心很多适合中小规模项目快速落地Milvus的部署虽然复杂但在更大规模、更复杂查询场景下潜力更大。我在实际项目中选择的是两者并用——业务上对延迟敏感且向量量级适中的应用走Qdrant对数据规模和查询复杂性要求更高的场景交给Milvus。无论选择哪个K8s和Helm这套部署方案都能让你在环境迁移、扩容和故障恢复时节省大量时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑