
最近一次小范围调研揭示了一个有趣的现象:在当前主流的RAG知识库应用场景中,向量数据库的成本有时能占到总支出的 ~45%,仅次于大模型(LLM)的调用费用。
因此,如何有效优化向量数据库的成本就成为了一个关键课题。本文将以 Milvus 为例,探讨如何利用其高级特性与合理的运维策略,来实现显著的成本降低。
01 Milvus 成本维度详解
在生产环境中,Milvus 的成本主要集中在这三类资源:实例(CPU + 内存)、网络、存储。我们以 1 亿(100M)条 768 维的 float32 向量为例进行分析:
成本占比分布(典型生产环境,100M 向量、768 维、float32)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
█████████████████████████ 实例(cpu+内存)(85-90%) ~$2,800/月
██ 网络(5-10%) ~$250/月
█ 存储(2-5%) ~$100/月
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
总计:~$3,150/月(基于 AWS 标准定价估算)
维度 1:内存(85-90%)
内存成本高昂,其核心原因并非单纯存储数据,而在于确保索引查询的高性能。像 HNSW、IVF 这类索引结构,若想实现毫秒级延迟,通常需要将其完全常驻内存,而这直接推高了账单。
内存需求计算公式:
内存需求 = 向量数据大小 × 索引内存倍数
= (N × D × 4 bytes) × 索引倍数
实际案例:100M 向量 × 768 维 × 4 bytes × 1.8x (HNSW)
= 307GB × 1.8 = 553GB
→ 需要至少 768GB 总内存(含 OS/缓存/峰值冗余)
→ AWS r6i.8xlarge (256GB × 3 台) ≈ $2,800/月
内存成本是向量数据库中绝对的大头,自然也成为成本优化的首要目标,后文将重点分析。虽然在高 QPS(>1000)或频繁构建索引的场景下也需要关注 CPU,但在大多数情况下,内存是实例选型的决定性因素。
维度 2:网络(5-10%)
网络成本的核心并非查询返回的 TopK 结果大小,而在于是否存在跨可用区(AZ)或跨区域的流量,以及是否返回了原始向量或大文本字段。生产环境中常见的优化手段包括:
- 只返回必要字段(如 ID、相似度分数、必要的元数据)。
- 避免跨区域调用和跨区域副本同步。
- 合理控制副本策略与数据同步开销。
通过这些优化,网络成本通常可以得到有效控制,无需过度担忧。
维度 3:存储(2-5% 的总成本)
存储是 Milvus 成本中占比最低的部分。得益于存算分离架构,所有向量数据和索引文件都持久化在对象存储(如 S3、MinIO)中,查询时按需加载。对象存储的价格极低,大约只有内存成本的 1/200。
存储成本估算(100M 向量 × 768 维 × float32):

即使配置多副本或跨区域备份,存储成本通常也只会增加到 $50-150/月 的范围,远非成本消耗的主力。
02 内存优化策略
2.1 索引优化:选择正确的索引类型降低 4 倍内存
同样是存储 1 亿条 768 维 float32 向量,原始数据约 300GB。
- FLAT/IVF_FLAT 索引 基本等同于原始向量大小,内存需求约 300GB。
- HNSW 索引 由于额外的图结构开销,通常需要 1.5–2.0 倍内存(约 450–600GB)。
- IVF_SQ8 索引 通过将 float32 压缩为 uint8,实现 4 倍压缩,内存需求可降至 75–100GB。
- IVF_PQ 或 DiskANN 在更激进压缩或磁盘索引模式下,内存可进一步降低到 30–60GB。
由此可见,在相同数据规模下,不同索引之间的内存差距可达到 4–6 倍。许多项目初期默认选择 HNSW 或 IVF_FLAT 以追求极致召回率和低延迟,却忽略了背后的成本代价。实际上,通过合理的索引选择和参数调优,完全可以在保持 95% 以上召回率的前提下,将内存成本降低 70-85%。以下是对比表格,基于 Milvus 官方文档和性能测试数据(假设 float32 向量、L2 距离、单内存副本):

- FLAT:无压缩,精度最高但速度最慢,仅适合小规模场景。
- IVF 系列:通过聚类加速查询,IVF_SQ8 是成本与性能的最佳平衡点。
- HNSW:查询速度最快但内存开销最大,适合低延迟优先场景。
- DiskANN:磁盘索引,内存占用极低,但需要高性能 SSD 支持。
在典型的 RAG 场景中,IVF_SQ8 相比 IVF_FLAT 的召回率通常仅下降 2-3%(从 97% 降至 94-95%),但内存成本却能降低 70%。这对绝大多数应用而言,是一个非常划算的权衡。如果对召回率要求可以进一步放宽,还可以考虑 IVF_PQ 或 IVF_RABITQ 这类深度量化索引来节省更多内存。
2.2 内存与存储优化:Mmap 与分层存储节省 60-80% 内存
Milvus 提供了两种关键技术来降低内存常驻成本:MMap(Milvus 2.3+)和分层存储(Milvus 2.6+)。
MMap(Memory-Mapped File) 将本地磁盘文件映射到进程的虚拟地址空间,依靠操作系统的 Page Cache 实现按需加载。数据访问触发缺页中断(Page Fault),系统自动从本地磁盘读取数据到物理内存。MMap 无法直接映射对象存储,数据需先从 S3/MinIO 下载到 QueryNode 的本地磁盘。因此,它会引入额外的本地存储成本,但相较于节省的巨大内存开销,净收益依然非常可观。
分层存储 则将本地磁盘的角色从“数据容器”转变为“热数据缓存”。数据不再全量下载,而是按需从对象存储拉取并缓存在本地。对象存储层持久化全量数据,成本极低($0.02-0.04/GB/月);本地缓存层仅存放热数据,容量远小于全量数据。
系统启动时仅加载元数据(MB级),启动时间缩短至秒级。查询时,若缓存命中则直接返回(延迟 <5ms);若未命中,则从对象存储拉取数据(延迟 50-200ms)并加入缓存。
Mmap 和分层存储都依赖本地磁盘,推荐使用 NVMe SSD(IOPS > 10,000)以获得更好的性能。
- MMap:节省内存,不节省本地磁盘空间,延迟稳定。
- 分层存储:同时节省内存和本地磁盘空间,但缓存未命中时延迟较高。
两者的数据流对比如下:
【传统全加载】
对象存储 ──全量加载──→ 内存(100% 常驻)
↑
成本最高
【MMap】
对象存储 ──全量下载──→ 本地磁盘(100%)──按需加载──→ 内存(10-30%)
↑ ↑
新增成本 大幅节省
【分层存储】
对象存储 ←─按需拉取─→ 本地缓存(10-30%)──按需加载──→ 内存(无要求)
↑ ↑ ↑
持久层 大幅节省 大幅节省
如何选择 Mmap 和分层存储方案?

2.2.1 MMap 配置方法
方式 1:YAML 配置(推荐用于新部署)
编辑 Milvus 配置文件 milvus.yaml,在 queryNode 部分添加:
queryNode:
mmap:
vectorField: true # 向量数据
vectorIndex: true # 向量索引(最大节省来源!)
scalarField: true # 标量数据(RAG 场景推荐)
scalarIndex: true # 标量索引
growingMmapEnabled: false # 增量数据保持在内存
方式 2:Python SDK 配置(适用于现有 Collection)
from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530")
# 必须先卸载 Collection,才能修改 mmap 属性
client.release_collection("my_collection")
# 启用 MMap
client.alter_collection_properties(
collection_name="my_collection",
properties={"mmap.enabled": True}
)
# 重新加载(应用 MMap 配置)
client.load_collection("my_collection")
# 验证配置是否生效
print(client.describe_collection("my_collection")["properties"])
# 输出: {'mmap.enabled': 'True'}
2.2.2 分层存储配置详解(Milvus 2.6+)
编辑 Milvus 配置文件 milvus.yaml,在 queryNode 部分添加:
queryNode:
segcore:
tieredStorage:
warmup:
# 选项: sync, async, disable
# 指定分层存储缓存预热的时机。
# - "sync": 在 Segment 被视为加载完成之前,数据会先加载到缓存中。
# - "disable": 不会主动将数据加载到缓存中,仅在 Search/Query 任务需要时才加载。
# 默认值为 "sync",但向量字段默认为 "disable"。
scalarField: sync
scalarIndex: sync
vectorField: disable # 向量字段原始数据的缓存预热默认关闭。
vectorIndex: sync
memoryHighWatermarkRatio: 0.85 # 内存使用超过 85% 开始淘汰
memoryLowWatermarkRatio: 0.70 # 淘汰到 70% 停止
diskHighWatermarkRatio: 0.80 # 磁盘淘汰高水位
diskLowWatermarkRatio: 0.75 # 磁盘淘汰低水位
evictionEnabled: true # 必须开启!
backgroundEvictionEnabled: true # 后台淘汰线程
cacheTtl: 3600 # 1 小时未访问自动淘汰
2.3 降维策略:从根源上削减存储需求
维度对成本的显著影响
向量维度是成本的基础乘数。内存消耗、存储空间、计算开销都与维度成正比。例如,1536 维的 text-embedding-3-small 模型相比 384 维的 all-MiniLM-L6-v2,在向量数量相同时,内存需求是后者的 4 倍。
降维不仅降低存储成本,还能减少查询时的计算复杂度。余弦相似度计算的时间复杂度为 O(D),768 维向量的计算就比 384 维慢一倍。在高 QPS 场景下,降维能直接提升吞吐量,从而减少所需的计算节点数量。
Embedding 模型对比表
以下数据基于 OpenAI 和开源模型的官方基准测试,相对成本以 384 维模型为基准(1.0x):

建议先用小数据集(例如 100 万向量)测试不同维度模型的召回率,找到满足业务需求的最小维度后,再进行全量部署。除了直接选择低维模型,还可以通过主成分分析(PCA)、Matryoshka Embeddings 等后处理技术进一步压缩向量维度。
2.4 数据生命周期管理:Compaction + TTL
在 Milvus 的存储模型中,数据采用追加写入方式组织。删除操作通常以逻辑删除标记实现,并不会立即回收底层物理存储空间。如果缺乏有效的生命周期管理,长期运行的系统会逐渐积累大量无效数据(已删除或过期),导致:
- 存储空间持续增长。
- Compaction 任务压力增大。
- 查询时需要扫描的 segment 数量增多,影响效率。
- 备份与数据同步成本也随之上升。
因此,数据生命周期管理是控制长期总拥有成本(TCO)的必要机制。
机制一:Compaction —— 回收逻辑删除空间
Compaction 通过合并小 segment、清理删除标记,生成新的、紧凑的 segment,从而释放被无效数据占用的存储空间。
适用场景:
- 高写入频率 + 高频删除(如商品上下架、内容更新、日志流处理)。
- Segment 数量持续增加。
- 存储使用率异常增长。
需要注意的是,Compaction 是一个资源消耗较高的任务,建议在业务低峰期(如凌晨)执行。
机制二:TTL(Time to Live)—— 自动过期控制
对于天然具有时效性的数据(如日志、会话记录、新闻、事件流),TTL 是更高效的控制手段。TTL 的作用是:
- 为数据设置一个生存时间窗口。
- 自动将超过期限的数据标记为删除状态。
- 最终结合 Compaction 任务释放物理空间。
TTL 的典型场景:
- 只需保留最近 7 天或 30 天的数据。
- 基于时间衰减的 RAG 系统。
- 实时推荐系统。
03 云上的另一个选择
对于已经在公有云上使用 Milvus 的用户,除了应用上述优化策略,由 Milvus 原厂提供的公有云托管服务 Zilliz Cloud (https://zilliz.com.cn/) 也是一个值得考虑的降本增效方案。关于 Zilliz Cloud 和开源 Milvus 的详细对比可参考其官方文档,其降本核心原因主要有两点:
- 性能更强的执行引擎 Cardinal:通过开源的向量数据库评测工具 VectorDBBench 可以看到,Zilliz Cloud 的整体性能通常是开源 Milvus 的 3-5 倍。这意味着,开源 Milvus 可能需要 5 台服务器才能达到的性能,Zilliz Cloud 用一台服务器即可实现。

- 近乎为 0 的运维成本:无需自行采购服务器、部署集群,也免去了繁琐的参数调优过程。前文提到的 MMap、分层存储、索引优化等降本策略,在 Zilliz Cloud 实例中已实现原生优化配置。
此外,Milvus 和 Zilliz Cloud 在数据和 API 接口层面完全兼容,迁移成本极低,官方也提供了成熟的迁移工具。关于使用 Zilliz Cloud 实现向量数据库成本优化的更多技术策略,未来会有专门的文章进行分享。
04 总结
本文深入剖析了向量数据库的成本结构,并定位内存为最主要的成本项。我们可以遵循以下步骤来系统性地优化 Milvus 的内存开销:
- 先改索引策略 —— 用 IVF_SQ8 等压缩量化索引替代默认的高内存消耗索引(如 HNSW)。
- 再改加载方式 —— 根据场景启用 MMap 或分层存储,将数据从“全量常驻内存”转变为“按需加载”。
- 最后实施生命周期管理 —— 利用 TTL 和定期的 Compaction 来控制数据的长期膨胀。
如果你已在云上自建 Milvus,但不希望投入过多工程资源进行繁琐的运维,同时追求极致的性价比,那么 Zilliz Cloud 是一个不错的选择。它通过高性能引擎提升单位资源吞吐,并将扩缩容、参数优化等复杂性平台化。在相同的服务等级协议(SLA)下,通常意味着需要更少的计算节点、更低的硬件成本,以及接近零的日常运维负担。
希望这篇实战指南能帮助你更好地驾驭 Milvus,实现成本与性能的平衡。如果你想与更多开发者交流此类Deep Learning基础设施的优化心得,欢迎来云栈社区一起探讨。