最近在做RAG应用,数据量大概在千万级embedding(768维),用的是bge-large模型。目前本地测试用了Milvus(standalone模式),但插入数据后查询延迟不太稳定,有时候20ms,有时候飙到200ms+。也试了Qdrant的docker版,感觉接口更简单,但社区案例好像没Milvus多。
向量数据库选型实战求助:Milvus和Qdrant在千万级数据下怎么选?
全部回复
共 54 条千万级768维这个量级,延迟波动大概率不是引擎本身的问题,先看下你Milvus的索引类型和构建参数,HNSW的M和efConstruction调过没?我之前遇到过类似情况,把segment大小和缓存策略调一下能稳定不少。Qdrant上手确实快,但真到生产环境要自己折腾的东西也不少,比如集群部署和压缩算法。另外可以试试把bge-large换成bge-m3,查询速度能快一截,精度掉得也不多。你测试时是纯查询还是带着filter?
巧了,我上个月刚做完一轮类似的压测,也是768维,不过数据量在五百万左右。你那个延迟抖动的问题,我怀疑不一定是向量库本身的问题,Milvus standalone模式下,查询路径里有个叫“knowhere”的索引构建参数,如果min_pts_per_node没调好,在数据分布不均匀时确实会忽快忽慢。Qdrant那边我反而觉得它的HNSW参数暴露得更清楚,而且它默认会用mmap映射文件,冷热数据切换时延迟会更可控一些。但要说社区案例,Milvus确实多,尤其是中文资料,真出问题能搜到的答案多很多。我现在是主力用Qdrant,因为它的过滤查询和payload索引做得太顺手了,RAG场景里如果要做metadata筛选,这个优势会很明显。你千万级数据的话,建议先看看自己的查询是不是都命中了缓存,如果是有规律的重复查询,那200ms的尾部延迟大概率是磁盘IO或者GC造成的,跟选型关系不大。另外提醒一句,bge-large的向量分布比较聚拢,建议把ef构建参数调大一点,不然召回率会有点虚高。
我之前也卡在这俩上纠结了好久,最后选了Milvus但把部署方式调成了分布式。你那个延迟抖动大概率是standalone模式下segment合并和索引构建抢资源导致的,可以试试在插入时调大index_building_max_capacity或者干脆用批量导入,别一条条upsert。Qdrant的接口确实清爽,而且filter+向量混合过滤性能很稳,但千万级768维的话,内存占用你得仔细算算,docker版默认配置容易OOM。另外你测延迟的时候是不是没开缓存?Milvus的warmup对热点查询影响很大,冷启动200ms很正常。如果你们业务对P99延迟敏感,我反而建议先压测Qdrant,它内部用HNSW的ef参数调优更直观,Milvus的调参链路太长。不过社区资源这块Milvus确实碾压,遇到问题Stack Overflow一搜就有解,Qdrant有些坑只能翻GitHub issue。最后提醒下,千万级数据量建议直接上分片,单机再怎么调也就那样。
之前做类似规模的项目也踩过这个坑,延迟抖动大概率不是数据库本身的问题,而是跟索引构建参数和段合并策略有关。Milvus standalone模式下,如果没设置好index_type和nlist,或者数据插入后还没触发段合并,查询就会走暴力扫描,延迟自然忽高忽低。我后来把HNSW的M参数调到64,并且定期执行flush和compact,200ms的情况基本消失了。Qdrant那边我倒是觉得它在单机性能上更稳,尤其对内存的管控比Milvus要精细,但你要说千万级规模,社区案例少不代表不行,只是出了问题得自己多翻源码。另外不知道你测试时并发量是多少,如果只是单线程压测,那20ms和200ms的差异可能更多是缓存命中率造成的。建议你先把WAL和刷盘策略调一下,看看索引文件是否全部加载到内存,再考虑换不换库。其实向量数据库选型到最后拼的都是运维调优能力,接口简单只是前期省心。
千万级768维这个量级其实两边都能扛住,但延迟抖动大概率不是数据库本身的问题,你查过bge-large的推理链路吗?我之前也遇到过类似情况,后来发现是embedding服务偶尔GC导致整体链路变长,单独测数据库其实很稳定。Milvus standalone模式在千万级数据下确实会有内存映射的瓶颈,尤其你如果没开mmap或者索引类型没选对,HNSW的参数调不好就会出现你说的20ms到200ms的跳变。Qdrant的接口设计确实更友好,而且它的payload过滤和向量检索结合得比Milvus顺手,但社区案例少不代表不行,你看Github上它的issue响应速度其实挺快的。我自己的经验是,如果团队没人专门维护基础设施,Qdrant的docker-compose一把梭更省心,Milvus要玩好得熟悉它的分片和索引生命周期管理。另外建议你测一下同样数据量下,两边构建索引的时间和内存占用,有时候插入慢比查询慢更致命。最后想问下,你说的200ms是发生在并发查询的时候,还是单条查询也会这样?如果是并发,那可能要先看下你的连接池和查询参数里有没有设置limit。
千万级768维这个量级,其实两个都能扛,但延迟抖动大概率是Milvus standalone的索引构建和段合并策略导致的,试试调大sync_interval或者换HNSW参数,能把尾部延迟压下来。Qdrant的API确实省心,不过它的payload过滤在千万级纯向量场景下优势不明显,反而Milvus的GPU索引和分布式扩展上限更高。顺便问下你测试时是纯向量检索还是带了标量过滤?带filter的话这俩的差距会拉大,我这边之前跑过类似规模,Qdrant在复杂过滤下内存占用会涨得比较快。
说实话你这情况我去年也踩过,千万级768维真不是闹着玩的。Milvus standalone那个延迟抖动,我怀疑跟segment合并和compaction时机有关系,尤其你插入和查询并发的时候,内存索引和磁盘索引切换那一下能飙到几百毫秒,建议你试试调下segment size和index building interval,别让它太频繁触发。
Qdrant这边接口确实是舒服,RESTful + gRPC都齐全,而且它默认就是HNSW,配置项少很多,对小团队友好。但你说社区案例少,其实也分场景,如果是纯RAG + 过滤查询,Qdrant的payload索引做得比Milvus顺手多了,filter性能差距在千万级下会拉得很大。
我自己的经验是,如果检索模式比较固定,比如只按top_k召回不搞复杂混合检索,Qdrant够用,而且docker版资源占用比Milvus standalone小一半不止,部署省心。但你要是后续要上GPU加速或者做标量+向量联合查询,Milvus的扩展性上限更高,只是需要你花时间调优。
另外你那20ms到200ms的波动,强烈怀疑是没开warmup或者collection的replica数量不够,Milvus默认配置对延迟敏感型负载不太友好。可以先试试把cache容量加大,把索引类型换成IVF_SQ8,精度损失一点但延迟会稳很多。
最后问一句,你这千万级是纯向量还是有大量metadata过滤?如果有,我建议先拿Qdrant跑个filter+vector的压测,看看p99能不能接受,这往往是决定性的。
千万级还是得看索引和分片,Milvus延迟抖动大概率是compaction闹的,试试调下参数。Qdrant上手快但集群坑多,建议压测再看。
延迟抖动先看下磁盘和GC配置,Milvus standalone调好参数其实挺稳的。Qdrant上手快但千万级真出问题社区资料少,我建议先压测再定。
千万级这个量级别光看延迟,Milvus要调segment和索引参数,Qdrant胜在省心,但出坑只能自己趟。我最后留了Milvus,主要是调优文档全。
千万级的话建议先压测Qdrant,延迟稳定性往往比Milvus好调,接口简单后期运维也省心。
Milvus standalone这个延迟波动大概率是segment合并和索引构建闹的,Qdrant的HNSW参数调好会稳很多。
千万级768维这个量级,延迟抖动大概率不是引擎本身的问题,更像是在standalone模式下磁盘IO或者内存淘汰策略触发了瓶颈。Qdrant的接口确实省心,但Milvus胜在生态和索引参数可调性,比如试试调大chunk_size或者换HNSW的M值,看看能不能把尾延迟压下来。另外想确认下,你测试时Qdrant是默认配置还是也做了调优?我有点怀疑docker版默认参数在千万级上同样会吃性能,只是你没跑到那个压力点而已。
千万级768维这个量级我也踩过类似的坑,Milvus standalone的延迟抖动大概率跟segment合并和内存索引构建有关,试试调低snapshot的间隔或者换HNSW的M参数可能会有改善。Qdrant的接口确实清爽,但如果你后续要上复杂的filter或者标量混合查询,它的性能调优文档比Milvus薄不少。另外你测过召回率吗,bge-large的向量分布有时候挺吃索引参数,两个库默认配置下不一定都最优。建议先拿真实query集跑一遍 recall@10 对比,别只看延迟。
千万级768维用standalone跑Milvus确实容易这样,延迟抖动大概率是索引没选对或者segment合并时抢了资源,你查下是不是还在用FLAT或者HNSW参数没调。Qdrant的过滤和payload索引做得挺顺手,单机性能也不差,但分布式这块案例确实少一些。我之前类似规模用Milvus配HNSW加适当增大segment size,延迟能压到比较稳的区间,你可以先调参再决定换不换。
Milvus standalone 延迟抖动挺常见的,大概率是索引没建对或者 segment 没 compact,千万级建议上 HNSW 加调大 nlist,另外 standalone 本身资源隔离差,内存一紧张就飙延迟。Qdrant 我也用过,接口确实清爽,过滤检索做得比 Milvus 顺手,但生态和分布式成熟度差一截。如果单机扛得住、团队人手少,Qdrant 其实挺香的;要往上扩到亿级或者要混合检索,还是 Milvus 更稳。你那边 QPS 大概多少?这个量级下并发一上来选型结论可能完全不一样。