最近在做一个图片查重的小项目,用的Milvus 2.3,索引类型是IVF_FLAT,nlist设了1024,数据量大概50万条128维向量。单机部署,16核32G内存,本地测试单条查询延迟还行,但上线后并发一高(大概200QPS),CPU直接飙到90%,响应时间从20ms涨到200ms+。自己试了调大nprobe、换HNSW索引,效果不明显。想问下各位大佬,这种场景是硬件瓶颈还是参数没调好?有没有必要上GPU或者换分布式方案?另外,业务上允许一点精度损失,像PQ量化这种是不是能换来性能提升?希望有实战经验的朋友指点一下,谢谢!
用向量数据库做相似图片检索,QPS上不去怎么优化?
全部回复
共 146 条50万向量真不大,瓶颈八成在CPU和内存带宽,先试试PQ+IVF,200QPS应该能稳。
50万向量这个量级真不算大,你这配置单机跑200QPS理论上不该这么拉胯,先看看是不是没走批量查询接口,或者客户端连接池打满了。IVF_FLAT在这种并发下确实容易吃CPU,因为要扫的桶太多,你可以试试把nlist降到512甚至256,配合nprobe控制在8左右,召回率降一点但延迟会好看很多。PQ量化肯定是值得试的,128维压到32维,内存带宽和CPU开销直接降一个量级,我这边之前用IVF_PQ把类似场景的QPS从150提到400+,精度损失大概2%以内,业务基本无感。至于GPU或者分布式,我觉得真没必要,先查一下Milvus的配置是不是把mmap给关了,还有索引文件是不是全在内存里,这个数据量HNSW调好参数应该也能扛住。
50万条128维其实不算大,IVF_FLAT在200QPS下CPU打满,八成是nprobe给太高了,你可以先把nprobe压到16-32试试,召回掉一点但延迟会好很多。另外Milvus单机查询走的是CPU,HNSW建索引慢但查询更吃内存,你32G可能不太够它吃。PQ量化确实能换性能,50万这个量级用IVF_PQ或者SQ8都挺合适,精度损失一般业务能接受。真要上200QPS稳定跑,建议先看下是不是每次查询都带了标量过滤,那个才是隐形杀手。
50万条128维用IVF_FLAT,200QPS就CPU 90%其实挺正常的,IVF本身在并发下计算量就大。你可以先试试把nlist降到256或512,nprobe保持16左右,召回率损失不大但单次扫描的聚类数少了,CPU能降不少。另外50万数据量上HNSW确实更合适,但得把M和efConstruction调小点,不然内存和建索引时间都会炸。PQ量化能省内存但对CPU帮助有限,你这瓶颈更像是计算密集不是内存带宽,真要上量还是得分片或者走GPU版Milvus。
50万数据IVF_FLAT还200QPS就跪,先查查是不是没开mmap或者nprobe给太高了。PQ确实能救,但128维压太狠精度掉得厉害,可以试试IVF_PQ。
50万条128维的数据其实不算大,IVF_FLAT在200QPS下CPU飙到90%不太正常,你nprobe设的多少?如果nprobe设太高比如64以上,那基本等于暴力扫一大半聚类,CPU肯定扛不住。另外16核32G单机跑Milvus,milvus本身还有不少后台线程和segment合并开销,查询一密集资源抢得厉害。你换HNSW没效果我猜是没调efSearch,默认值可能偏大,HNSW在高并发下内存随机访问的模式反而更吃CPU cache,不一定比IVF省。PQ量化确实能换性能,50万条128维用PQ或者IVF_PQ,内存和计算量都能明显降,精度损失在查重场景一般能接受,但建议先用OPQ或者带残差的PQ。真正要提QPS,先确认瓶颈到底在向量检索还是在你前后处理,比如图片特征提取、网络IO这些,用Milvus的metrics或者perf工具看下各阶段耗时。如果确实是检索本身,可以考虑把nlist调大一点比如4096配合小nprobe,或者直接上GPU版Milvus,200QPS这个量级GPU基本轻松。分布式没必要,50万条单机足够,先压榨参数和硬件再说。