Milvus 配置开发人员指南
简介
作为使用 Milvus 的开发人员,你很可能遇到过令人生畏的milvus.yaml 配置文件,其中包含 500 多个参数。当你只想优化你的向量数据库性能时,处理这种复杂性是很有挑战性的。
好消息是:你不需要了解每个参数。本指南将剔除杂音,重点关注对性能有实际影响的关键设置,并明确指出应根据具体使用情况调整哪些值。
无论你是在构建一个需要闪电般快速查询的推荐系统,还是在优化一个有成本限制的向量搜索应用,我都会告诉你到底该用哪些实用的、经过测试的值来修改参数。在本指南结束时,你将知道如何根据实际部署情况调整 Milvus 配置,以获得最佳性能。
配置类别
在深入了解具体参数之前,我们先来了解一下配置文件的结构。在使用milvus.yaml 时,你需要处理三个参数类别:
依赖组件配置:Milvus 连接的外部服务 (
etcd,minio,mq) - 对集群设置和数据持久性至关重要内部组件配置:Milvus 的内部架构 (
proxy,queryNode, 等等) - 性能调整的关键功能配置:安全、日志和资源限制--对生产部署很重要
Milvus 依赖组件配置
让我们从 Milvus 依赖的外部服务开始。当从开发阶段转向生产阶段时,这些配置尤为重要。
etcd:元数据存储
Milvus 依赖etcd 进行元数据持久化和服务协调。以下参数至关重要:
Etcd.endpoints:指定 etcd 集群的地址。默认情况下,Milvus 会启动一个捆绑实例,但在企业环境中,最佳做法是连接到托管的etcd服务,以获得更好的可用性和操作控制。etcd.rootPath:定义在 etcd 中存储 Milvus 相关数据的关键前缀。如果在同一 etcd 后端操作多个 Milvus 集群,使用不同的根路径可实现干净的元数据隔离。etcd.auth:控制身份验证凭据。Milvus 默认不启用 etcd auth,但如果托管的 etcd 实例需要凭据,则必须在此处指定。
minio:对象存储
尽管名称如此,但该部分管理所有与 S3 兼容的对象存储服务客户端。它通过cloudProvider 设置支持 AWS S3、GCS 和阿里云 OSS 等提供商。
请注意以下四项关键配置:
minio.address / minio.port:使用这些配置指定对象存储服务的端点。minio.bucketName:分配单独的存储桶(或逻辑前缀),以避免运行多个 Milvus 集群时发生数据碰撞。minio.rootPath:启用桶内命名,以实现数据隔离。minio.cloudProvider:标识 OSS 后端。有关完整的兼容性列表,请参阅Milvus 文档。
mq:消息队列
Milvus 使用消息队列进行内部事件传播--Pulsar(默认)或 Kafka。请注意以下三个参数。
pulsar.address/pulsar.port:设置这些值以使用外部 Pulsar 集群。pulsar.tenant:定义租户名称。当多个 Milvus 集群共享一个 Pulsar 实例时,这将确保干净的通道分离。msgChannel.chanNamePrefix.cluster:如果你想绕过 Pulsar 的租户模型,请调整通道前缀以防止碰撞。
Milvus 还支持 Kafka 作为消息队列。要使用 Kafka,请注释掉 Pulsar 的特定设置,并取消注释 Kafka 配置块。
Milvus 内部组件配置
rootCoord:元数据 + 时间戳
rootCoord 节点处理元数据更改(DDL/DCL)和时间戳管理。
rootCoord.maxPartitionNum: 设置每个 Collections 的分区数上限。虽然硬限制是 1024,但该参数的主要作用是提供保障。对于多租户系统,应避免使用 Partition Key 作为隔离边界,而应实施可扩展至数百万逻辑租户的租户密钥策略。rootCoord.enableActiveStandby:通过激活备用节点实现高可用性。这一点至关重要,因为 Milvus 协调器节点默认情况下不会横向扩展。
proxy:API 网关 + 请求路由器
proxy 处理面向客户端的请求、请求验证和结果聚合。
proxy.maxFieldNum:限制每个 Collections 的字段(标量 + 向量)数量。保持在 64 个以下,以尽量减少 Schema 复杂性和 I/O 开销。proxy.maxVectorFieldNum:控制 Collections 中向量字段的数量。Milvus 支持多模式搜索,但在实践中,10 个向量字段是一个安全的上限。proxy.maxShardNum:定义摄取分片的数量。经验法则是< 2 亿条记录 → 1 个分片
2-4 亿条记录 → 2 个分区
超出后线性扩展
proxy.accesslog:启用后,会记录详细的请求信息(用户、IP、端点、SDK)。有助于审计和调试。
queryNode:查询执行
处理向量搜索执行和段加载。请注意以下参数。
queryNode.mmap:为加载标量字段和数据段切换内存映射 I/O。启用mmap有助于减少内存占用,但如果磁盘 I/O 成为瓶颈,可能会降低延迟。
dataCoord:分段 + 索引管理
该参数控制数据分段、索引、压缩和垃圾收集(GC)。主要配置参数包括
dataCoord.segment.maxSize:指定内存数据段的最大大小。较大的数据段通常意味着系统中的总数据段较少,这可以通过减少索引和搜索开销来提高查询性能。例如,一些使用 128GB 内存运行queryNode实例的用户报告说,将该设置从 1GB 增加到 8GB,查询性能大约提高了 4 倍。dataCoord.segment.diskSegmentMaxSize:与上述参数类似,该参数专门控制磁盘索引(diskann 索引)的最大大小。dataCoord.segment.sealProportion:确定增长的数据段何时被封存(即最终完成并建立索引)。当数据段的长度达到maxSize * sealProportion时,该数据段将被封存。默认情况下,在maxSize = 1024MB和sealProportion = 0.12时,将封存约 123MB 的数据段。
较低的值(如 0.12)会更早触发封存,这有助于更快地创建索引,对频繁更新的工作负载很有用处。
较高的值(如 0.3 到 0.5)会延迟封存,减少索引开销,更适合离线或批量摄取的情况。
dataCoord.segment.expansionRate: 设置压缩过程中允许的扩展因子。Milvus 计算压缩过程中允许的最大数据段大小为maxSize * expansionRate。dataCoord.gc.dropTolerance:段压缩或 Collections 丢弃后,Milvus 不会立即删除底层数据。相反,它会标记要删除的数据段,并等待垃圾收集 (GC) 周期完成。该参数可控制延迟时间的长短。
其他功能配置
log:可观察性和诊断
健全的日志记录是任何分布式系统的基石,Milvus 也不例外。配置完善的日志设置不仅有助于在出现问题时进行调试,还能确保随着时间的推移更好地了解系统的健康状况和行为。
对于生产部署,我们建议将 Milvus 日志与集中式日志和监控工具(如Loki)集成,以简化分析和警报。关键设置包括
log.level:控制日志输出的冗长程度。对于生产环境,请坚持使用info级别,以捕获重要的运行时细节,而不会使系统不堪重负。在开发或故障排除过程中,可以切换到debug,以便更细致地了解内部操作。⚠️ 在生产环境中应谨慎使用debug级别--它会生成大量日志,如果不加以控制,会迅速占用磁盘空间并降低 I/O 性能。log.file:默认情况下,Milvus 会将日志写入标准输出(stdout),这适合通过 sidecars 或节点代理收集日志的容器化环境。要启用基于文件的日志记录,可以配置以下内容:
旋转前的最大文件大小
文件保留期
要保留的备份日志文件数量
这对于无法使用 stdout 日志传输的裸机或内部环境非常有用。
security:身份验证和访问控制
Milvus 支持用户身份验证和基于角色的访问控制(RBAC),两者都在common 模块下配置。这些设置对于保护多租户环境或任何暴露于外部客户端的部署至关重要。
主要参数包括
common.security.authorizationEnabled:此切换可启用或禁用身份验证和 RBAC。默认情况下是关闭的,这意味着允许所有操作而无需身份检查。要执行安全访问控制,请将此参数设置为true。common.security.defaultRootPassword:启用身份验证后,此设置将定义内置root用户的初始密码。
启用身份验证后,请务必立即更改默认密码,以避免在生产环境中出现安全漏洞。
quotaAndLimits:速率限制和写入控制
milvus.yaml 中的quotaAndLimits 部分在控制数据如何流经系统方面起着至关重要的作用。它管理插入、删除、刷新和查询等操作的速率限制,确保群集在繁重工作负载下的稳定性,并防止因写放大或过度压缩而导致性能下降。
主要参数包括
quotaAndLimits.flushRate.collection:控制 Milvus 从 Collections 中刷新数据的频率。
默认值为
0.1表示系统允许每 10 秒刷新一次。刷新操作会封存不断增长的数据段,并将其从消息队列持久化到对象存储空间。
过于频繁地刷新会产生许多小的封存段,从而增加压缩开销并降低查询性能。
💡 最佳实践:在大多数情况下,让 Milvus 自动处理。不断增长的数据段一旦达到maxSize * sealProportion 就会被封存,封存的数据段每 10 分钟刷新一次。只有在知道没有更多数据时,才建议在批量插入后进行手动刷新。
此外,请记住:数据可见性是由查询的一致性级别决定的,而不是刷新时间,因此刷新并不会使新数据立即可查询。
quotaAndLimits.upsertRate/quotaAndLimits.deleteRate :这些参数定义了上载和删除操作的最大允许速率。
Milvus 依赖于 LSM-Tree 存储架构,这意味着频繁的更新和删除会触发压缩。如果管理不慎,这可能会耗费大量资源,并降低总体吞吐量。
建议将
upsertRate和deleteRate的速度上限设定为0.5 MB/s,以避免压缩管道不堪重负。
🚀 需要快速更新大型数据集?使用 Collections 别名策略:
将新数据插入一个全新的 Collection。
更新完成后,将别名重新指向新的 Collections。这样可以避免就地更新带来的压缩惩罚,并实现即时切换。
真实世界配置示例
让我们通过两个常见的部署场景,来说明如何调整 Milvus 配置设置,以满足不同的操作目标。
示例 1:高性能配置
当查询延迟对任务至关重要时--想想推荐引擎、语义搜索平台或实时风险评分--每一毫秒都很重要。在这些使用案例中,您通常会使用HNSW或DISKANN 等基于图的索引,并优化内存使用和段生命周期行为。
主要调整策略:
提高
dataCoord.segment.maxSize和dataCoord.segment.diskSegmentMaxSize:根据可用内存,将这些值提高到 4GB 甚至 8GB。较大的分段可减少索引建立次数,并通过最大限度地减少分段扇出提高查询吞吐量。不过,更大的分段在查询时会消耗更多内存,因此要确保indexNode和queryNode实例有足够的空间。降低
dataCoord.segment.sealProportion和dataCoord.segment.expansionRate:在封存之前,将不断增长的分段大小锁定在 200MB 左右。这样可以保持段内存使用的可预测性,并减轻委托者(负责协调分布式搜索的查询节点领导者)的负担。
经验法则当内存充裕且延迟是优先考虑因素时,应选择更少、更大的数据段。如果索引的新鲜度很重要,则在密封阈值方面要保守一些。
💰示例 2:成本优化配置
如果您优先考虑的是成本效率而不是原始性能(常见于模型训练管道、低 QPS 内部工具或长尾图像搜索),您可以在召回率或延迟之间进行权衡,以大幅降低对基础架构的需求。
推荐策略:
使用索引量化:
SCANN、IVF_SQ8或HNSW_PQ/PRQ/SQ(Milvus 2.5 中引入)等索引类型可显著减少索引大小和内存占用。对于精度不如规模或预算重要的工作负载来说,这些类型是理想之选。采用磁盘支持索引策略:将索引类型设置为
DISKANN,以启用纯磁盘搜索。启用mmap,进行选择性内存卸载。
为节省大量内存,请启用mmap :vectorField,vectorIndex,scalarField, 和scalarIndex 。这样可以将大块数据卸载到虚拟内存,从而大幅减少常驻内存的使用。
⚠️ 注意事项:如果标量过滤是查询工作负载的主要部分,请考虑对vectorIndex 和scalarIndex 禁用mmap 。在 I/O 受限的环境中,内存映射会降低标量查询性能。
磁盘使用提示
使用
mmap建立的 HNSW 索引最多可将总数据量扩大1.8 倍。如果考虑到索引开销和缓存,100GB 的物理磁盘实际上只能容纳 ~50GB 的有效数据。
在使用
mmap时,一定要预留额外的存储空间,尤其是在本地缓存原始向量的情况下。
结论
调整 Milvus 并不是追求完美的数字,而是要根据工作负载的实际行为来塑造系统。最有影响力的优化通常来自于了解 Milvus 如何在压力下处理 I/O、段生命周期和索引。这些都是错误配置伤害最大的地方,也是经过深思熟虑的调整能获得最大回报的地方。
如果你是 Milvus 的新用户,我们介绍的配置参数将满足你 80-90% 的性能和稳定性需求。从这里开始。一旦建立了一定的直觉,请深入研究milvus.yaml 完整的规范和官方文档,您将发现细粒度的控制,这些控制可以将您的部署从功能性提升到卓越性。
有了正确的配置,您就可以根据操作的优先级构建可扩展的高性能向量搜索系统--无论是低延迟服务、高性价比存储,还是高测试分析工作负载。
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word



