如何利用内存映射及其他技术降低Milvus内存占用?
降低Milvus大向量集合内存占用的实用方案
针对你200万条512维float32向量的场景,结合内存映射及其他Milvus优化手段,以下是具体落地的优化方法:
1. 启用向量量化(最直接的内存压缩手段)
向量量化能将float32向量压缩为更低精度的格式,直接把原始向量的内存占用从4GB降到1GB左右,且大部分场景下检索精度损失可控:
- FLAT索引:改用
FLAT_SQ8索引类型,将float32转为int8存储 - IVF_FLAT索引:改用
IVF_SQ8,结合量化减少内存占用 - HNSW索引:改用
HNSW_SQ8,在保留HNSW检索性能的同时压缩向量体积
修改代码中的索引配置示例:
# FLAT_SQ8示例 index_type, params = 'FLAT', {'metric_type': 'L2', 'quantization_type': 'SQ8'} # IVF_SQ8示例 index_type, params = 'IVF_FLAT', {'nlist': 2000, 'quantization_type': 'SQ8'} # HNSW_SQ8示例 index_type, params = 'HNSW', {'M': 32, 'efConstruction': 200, 'quantization_type': 'SQ8'}
2. 优化内存映射的精细配置
除了开启mmap.enabled,还需调整以下参数进一步控制内存占用:
- 在Milvus的
values.yaml中设置queryNode.mmap.maxCachedBytes:限制Milvus内部缓存的mmap页面大小,比如设为1GB,避免系统缓存无限制占用物理内存 - 启用延迟加载:创建集合时添加
properties={'load.lazyLoad': True},让Milvus仅在查询时加载需要的Segment数据,而非一次性加载全量集合 - 关闭Milvus内部缓存:若完全依赖系统mmap机制,可设置
queryNode.cache.enabled: false,避免Milvus额外缓存向量数据
3. 针对不同索引类型的专属优化
- FLAT索引:由于FLAT无额外索引结构,全量向量会被mmap映射,此时可调整Linux系统参数
vm.swappiness(设为60-80),让系统更积极地将不常用的mmap页面换出到磁盘,减少物理内存占用 - IVF_FLAT索引:调大
nlist值(比如从2000增至4000),减少每个聚类中心对应的向量数量,查询时仅需加载部分Segment的向量数据,降低瞬时内存占用 - HNSW索引:适当降低
M值(比如从32降至16),减少HNSW索引结构的内存开销(每个节点的邻居数减少,索引体积减半),同时可接受的检索性能损失很小
4. 系统层面的内存管理优化
- 调整Linux内存参数:
# 提高系统对脏页的写入频率,避免内存被脏页占满 echo 10 > /proc/sys/vm/dirty_ratio echo 5 > /proc/sys/vm/dirty_background_ratio # 允许更多内存被交换到磁盘 echo 70 > /proc/sys/vm/swappiness - 确保服务器有足够的交换空间(Swap):至少配置与物理内存相当的Swap空间,让系统在内存紧张时能将mmap页面换出
5. 集合加载与资源隔离
- 避免同时加载多个集合:若不需要同时使用FLAT、IVF_FLAT、HNSW三个集合,仅加载当前需要的集合,用完后及时调用
release_collection()释放内存 - 配置QueryNode的资源限制:在
values.yaml中设置queryNode.resources.limits.memory为合理值(比如6GB),结合Kubernetes的内存限制机制,强制QueryNode控制内存占用
内容的提问来源于stack exchange,提问作者Tim Spann
相关产品推荐
相关产品推荐

