ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

向量数据库选型指南:Milvus、Qdrant、pgvector 等六大方案对比与实战

向量数据库选型指南:Milvus、Qdrant、pgvector 等六大方案对比与实战 1. 向量数据库选型的底层逻辑与核心思路向量数据库这两年火得很快但真正落到项目里选型的时候很多团队还是会卡住。原因不复杂市面上的方案看起来都能用但一旦把数据规模、延迟要求、运维成本、团队技术栈这几个维度摆到一起就会发现“能用”和“好用”之间差着十万八千里。我自己从最早用FAISS做小规模检索到后来在生产环境里跑Milvus、Qdrant、pgvector中间踩过的坑足够写一本小册子。这篇文章就把这些经验摊开来讲重点不是告诉你“哪个最好”而是帮你建立一套自己的选型判断框架。先说清楚一个前提向量数据库不是万能药。它的核心价值在于解决高维向量数据的近似最近邻搜索问题。传统数据库做精确匹配很快但面对128维、768维甚至1536维的向量用B树或者哈希索引去算距离计算量会爆炸。向量数据库通过ANN近似最近邻算法比如HNSW、IVF、PQ这些把搜索复杂度从线性降到对数级别代价是牺牲一点点召回率。这个trade-off是理解所有向量数据库设计的基础。选型的时候我一般会先问三个问题数据量级是多少查询延迟要求多低团队有没有专职运维这三个问题的答案基本能砍掉一半选项。比如数据量在百万级以下、延迟要求不苛刻、团队又只有Python开发那pgvector可能是最省心的选择但如果数据量上亿、QPS要求几千、还要支持多租户隔离那就得认真考虑Milvus或者Qdrant这类专用方案了。还有一个容易被忽略的点向量数据库的“语言”问题。这里的语言不是指编程语言而是指它支持的查询接口和生态集成方式。有些方案只提供REST API有些提供Python/Java/Go SDK有些直接兼容SQL。如果你的团队已经在用PostgreSQL那pgvector的SQL接口几乎零学习成本但如果团队是Java技术栈Qdrant的Java客户端和Milvus的Java SDK就需要额外评估。热词里出现的“qdrant java”和“向量数据库语言”其实指向的就是这个维度。提示选型时不要只看benchmark上的QPS数字那些数字通常是在理想硬件和特定数据集下跑出来的。真实业务里的向量分布、过滤条件、并发模式都会让性能打折扣。2. 六大主流方案的核心原理与架构拆解2.1 Milvus分布式架构的集大成者Milvus是我用得最久的向量数据库从0.8版本一路跟到2.x。它的架构设计很“云原生”存算分离、组件化、支持水平扩展。核心组件包括协调器、查询节点、数据节点、索引节点和对象存储。这种设计的好处是每个组件可以独立扩缩容比如查询压力大就加查询节点写入压力大就加数据节点。但代价是部署复杂度高单机版虽然能用Docker Compose跑起来但生产环境通常需要Kubernetes。Milvus支持的索引类型很全HNSW、IVF_FLAT、IVF_PQ、DISKANN都有。DISKANN是它的一个亮点能把索引放到磁盘上内存占用大幅降低适合超大规模数据。但DISKANN的查询延迟比内存索引高一个数量级所以适合对延迟不敏感的场景。另外Milvus的标量过滤能力在2.x版本之后增强了很多支持复杂的布尔表达式这对RAG场景很关键——你通常需要先按文档ID或者时间范围过滤再做向量检索。安装方面热词里提到的“milvus安装步骤详细教程”和“基于docker desktop安装milvus”确实是很多人的入门路径。用Docker Desktop跑单机版Milvus是最快的验证方式一条docker-compose up -d就能起来。但要注意单机版和集群版的配置差异很大单机版默认用的是本地存储集群版需要配置MinIO或者S3。如果后续要迁移数据迁移是个麻烦事。2.2 Pinecone全托管服务的代表Pinecone走的是完全不同的路线全托管、零运维、按量付费。你不需要关心索引怎么建、节点怎么扩只需要调API就行。这对初创团队或者没有专职运维的公司很有吸引力。Pinecone的底层实现没有公开但从性能表现看应该是用了优化的HNSW变种。它的优势在于稳定性和易用性控制台做得很直观SDK也很简洁。但Pinecone的问题也很明显数据必须放在它的云上对于数据合规要求高的行业比如金融、医疗可能是个障碍。另外成本随着数据量和查询量线性增长数据量大了之后账单会很可观。我见过一个团队用Pinecone跑了一年数据量从百万涨到五千万月账单从几十美元涨到几千美元最后不得不迁移到自建方案。2.3 QdrantRust写的高性能选手Qdrant是用Rust写的这个语言选择本身就说明了它的定位性能优先、内存安全、并发能力强。它的架构比Milvus简单很多单机版就是一个二进制文件下载下来直接跑不需要依赖一堆中间件。热词里的“qdrant本地搭建教程”和“qdrant下载”热度高说明很多人被它的轻量级吸引。Qdrant的过滤能力是我用过所有方案里最顺手的。它支持在向量检索的同时做复杂的payload过滤而且过滤条件可以嵌套、可以组合。比如你可以写一个条件category等于“技术”且publish_date大于某个时间戳且tags包含“数据库”然后在这个子集里做向量搜索。这种能力在RAG场景里非常实用因为知识库通常需要按权限、按分类、按时间做过滤。Qdrant的WebUI热词里的“windows qdrant webui”是个加分项可以在浏览器里直接查看集合、执行查询、调试过滤条件。对于开发阶段来说这比写代码调试快得多。另外Qdrant支持Java客户端热词“qdrant java”这对Java团队比较友好。2.4 pgvectorPostgreSQL的向量扩展pgvector的思路最“朴素”既然PostgreSQL这么强大为什么不直接给它加个向量类型和索引呢于是就有了pgvector。它的优势是零新增基础设施——你本来就在用PostgreSQL加个扩展就能做向量检索数据一致性、事务、备份这些都不用重新考虑。pgvector支持IVFFlat和HNSW两种索引。IVFFlat建索引快但查询慢HNSW查询快但建索引慢、内存占用高。实际用下来HNSW在大多数场景下更合适但要注意它的内存消耗。热词里的“windows如何安装pgvector”和“pgvector源码分析”说明很多人关心它的部署和实现细节。Windows上安装pgvector确实比Linux麻烦需要编译扩展通常建议用WSL或者Docker。pgvector的局限在于规模。当向量数量超过千万级查询性能会明显下降因为PostgreSQL的查询优化器对向量索引的支持还不够成熟。另外它的过滤和向量检索是分开的先过滤再检索或者先检索再过滤两种策略的性能差异很大需要根据数据分布来调。2.5 其他值得关注的方案除了上面四个还有两个方案值得提。一个是Weaviate它的特点是内置了模块化设计可以集成各种向量化模型适合不想自己调embedding的团队。另一个是Elasticsearch的向量检索功能如果你已经在用ES做全文检索加向量检索是最自然的扩展但ES的向量性能不如专用数据库。方案架构特点部署复杂度过滤能力适合规模Milvus分布式、存算分离高强亿级以上Pinecone全托管无中百万到千万Qdrant单机/集群、Rust低很强百万到亿级pgvectorPostgreSQL扩展低依赖SQL百万以下Weaviate模块化中强百万到千万ES向量全文检索扩展中强百万级3. 实操部署与核心环节实现3.1 Milvus单机版部署与索引调优先说Milvus的部署。用Docker Desktop是最快的路径但有几个细节要注意。首先Milvus单机版依赖etcd和MinIOdocker-compose文件里会一起拉起来。如果你的Docker Desktop内存分配不够默认可能只有2GBMilvus启动会失败。建议至少给到8GB。其次Milvus的端口映射要确认清楚默认是19530gRPC和9091HTTP。如果端口被占用改docker-compose里的映射就行。启动命令很简单wget https://github.com/milvus-io/milvus/releases/download/v2.3.0/milvus-standalone-docker-compose.yml -O docker-compose.yml docker-compose up -d启动之后用docker-compose ps确认三个容器都是healthy状态。然后可以用Python客户端连接from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType connections.connect(hostlocalhost, port19530) fields [ FieldSchema(nameid, dtypeDataType.INT64, is_primaryTrue), FieldSchema(nameembedding, dtypeDataType.FLOAT_VECTOR, dim768), FieldSchema(namedoc_id, dtypeDataType.VARCHAR, max_length128) ] schema CollectionSchema(fieldsfields) collection Collection(nametest_collection, schemaschema)建索引的时候HNSW的参数需要根据数据量调。M控制每个节点的连接数越大召回率越高但内存占用越大通常16到64之间。efConstruction控制建索引时的搜索范围越大索引质量越好但建索引越慢通常200到500。查询时的ef参数控制搜索范围越大召回率越高但延迟越高通常设为top_k的2到4倍。注意Milvus的索引参数一旦建好就不能直接改要改必须重建索引。所以建索引之前最好先用小批量数据测试不同参数的效果。3.2 Qdrant本地搭建与过滤实战Qdrant的本地搭建是我用过最顺的。下载二进制文件解压运行完事。Windows上直接下载exeLinux上可以用Dockerdocker run -p 6333:6333 -p 6334:6334 -v $(pwd)/qdrant_storage:/qdrant/storage qdrant/qdrant6333是HTTP端口6334是gRPC端口。启动之后打开浏览器访问http://localhost:6333/dashboard就能看到WebUI。在WebUI里可以创建集合、插入数据、执行查询调试过滤条件特别方便。Qdrant的过滤语法很直观。比如你要在category为“技术”且score大于0.8的子集里做向量搜索from qdrant_client import QdrantClient from qdrant_client.models import Filter, FieldCondition, MatchValue, Range client QdrantClient(hostlocalhost, port6333) search_result client.search( collection_namemy_collection, query_vector[0.1, 0.2, ...], query_filterFilter( must[ FieldCondition(keycategory, matchMatchValue(value技术)), FieldCondition(keyscore, rangeRange(gte0.8)) ] ), limit10 )这种过滤是在向量检索过程中执行的不是先检索再过滤所以性能很好。Qdrant的过滤条件支持嵌套、支持should/must/must_not组合表达能力很强。3.3 pgvector安装与查询优化pgvector的安装分两种情况。Linux上如果用的是PostgreSQL的官方仓库可以直接apt install postgresql-14-pgvector。Windows上麻烦一些需要先装Visual Studio的C编译工具然后从源码编译。热词里“windows如何安装pgvector”和“postgresql 14.24.2”说明很多人卡在这一步。我的建议是Windows上直接用Docker跑PostgreSQL然后装pgvector扩展省去编译的麻烦。docker run -d --name pgvector -e POSTGRES_PASSWORDpassword -p 5432:5432 pgvector/pgvector:pg14连接之后启用扩展CREATE EXTENSION vector; CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(768)); CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);查询的时候是余弦距离-是欧氏距离#是内积。注意pgvector的索引和查询必须用同一种距离度量否则索引不会生效。pgvector的性能调优有几个关键点。第一maintenance_work_mem要调大建HNSW索引的时候需要足够内存否则会走磁盘很慢。第二ef_search参数控制查询时的搜索范围可以在会话级别设置SET hnsw.ef_search 100;。第三如果过滤条件很多考虑用部分索引只对满足条件的数据建索引。3.4 RAG场景下的向量数据库集成热词里“rag向量数据库”和“python milvus 实现rag知识库”说明很多人关心RAG场景。RAG的核心流程是文档切块、向量化、存入向量数据库、查询时先检索再生成。向量数据库在这个流程里承担的是“记忆”角色。用Milvus做RAG知识库的典型代码结构from pymilvus import Collection from sentence_transformers import SentenceTransformer model SentenceTransformer(all-MiniLM-L6-v2) collection Collection(rag_knowledge) def add_document(text, doc_id): embedding model.encode(text).tolist() collection.insert([[doc_id], [embedding], [text]]) def search(query, top_k5): query_embedding model.encode(query).tolist() results collection.search( data[query_embedding], anns_fieldembedding, param{metric_type: COSINE, params: {ef: 64}}, limittop_k, output_fields[text] ) return [hit.entity.get(text) for hit in results[0]]这里有个坑embedding模型和向量数据库的维度必须匹配。all-MiniLM-L6-v2输出384维如果你建集合时设了768维插入会报错。另外文档切块的策略直接影响检索效果块太大噪声多块太小上下文不足。通常建议块大小在256到512个token之间重叠50到100个token。4. 常见问题与排查技巧实录4.1 性能不达预期的排查思路向量数据库性能不达预期通常不是单一原因。我一般按这个顺序排查先看索引类型对不对再看参数调没调然后看过滤条件是否走了索引最后看硬件资源够不够。索引类型方面HNSW适合高召回低延迟IVF适合高吞吐PQ适合内存受限。如果你用IVF_FLAT但nlist设得太小查询时会扫描太多簇延迟就高。nlist的经验值是sqrt(N)N是向量总数。nprobe控制查询时扫描的簇数越大召回越高但越慢通常设为nlist的10%到20%。过滤条件方面Milvus和Qdrant都支持在向量检索时做过滤但实现方式不同。Milvus的过滤是在查询节点执行的如果过滤条件选择性很高比如只筛出1%的数据性能会很好但如果选择性很低筛出90%过滤本身的开销就很大。Qdrant的过滤是在索引遍历时执行的对选择性低的场景更友好。硬件方面向量检索是内存密集型操作。HNSW索引的内存占用大约是向量数据本身的1.5到2倍。如果你有1000万个768维的向量原始数据约30GBHNSW索引可能需要45到60GB内存。内存不够就会走swap性能断崖式下跌。4.2 数据一致性与持久化的坑Milvus的持久化依赖etcd和MinIO如果MinIO挂了数据可能丢失。生产环境一定要配置MinIO的副本和备份。另外Milvus的flush操作是异步的插入数据后不会立即持久化需要手动调collection.flush()或者等自动flush。如果在这之前重启数据可能丢。Qdrant的持久化是默认开启的数据存在本地磁盘的storage目录。但要注意Qdrant的WAL预写日志默认是关闭的如果对数据安全性要求高需要在配置里开启。开启WAL会牺牲一点写入性能但能保证崩溃后数据不丢。pgvector的数据安全性直接继承PostgreSQL这方面最省心。但要注意pgvector的索引不是事务性的建索引的过程中如果崩溃索引可能损坏需要重建。4.3 常见问题速查表问题现象可能原因排查方法解决方案查询延迟高索引参数不合适检查ef/nprobe设置调大ef/nprobe或换索引类型召回率低索引质量差对比暴力搜索结果调大efConstruction/M插入报错维度不匹配embedding维度与集合定义不一致检查模型输出维度重建集合或换模型内存占用过高HNSW索引内存开销大监控内存使用换IVF_PQ或DISKANN过滤后结果为空过滤条件太严格逐步放宽条件检查字段类型和值集群版启动失败依赖组件未就绪检查etcd/MinIO状态按顺序启动依赖4.4 独家避坑经验第一个坑不要用默认参数上生产。Milvus和Qdrant的默认索引参数都是给demo用的真实数据上必须调。我见过一个团队直接用默认参数跑召回率只有60%调了参数之后到95%。第二个坑向量维度不是越高越好。OpenAI的text-embedding-3-large是3072维但很多场景下768维的模型效果差不多而存储和计算成本只有四分之一。选embedding模型的时候要权衡效果和成本。第三个坑批量插入比单条插入快得多。Milvus和Qdrant都支持批量插入一次插1000条比插1000次单条快几十倍。但批量太大也会导致内存问题通常1000到5000条一批比较合适。第四个坑不要忽略标量字段的索引。Milvus和Qdrant都支持为标量字段建索引这能大幅加速过滤操作。如果你的查询里经常按某个字段过滤一定要给它建索引。第五个坑测试环境的数据分布要和生产一致。我见过一个团队用随机向量测试性能很好但上线后发现真实数据的向量分布很集中HNSW的图结构退化查询性能下降了一半。测试时最好用真实数据的采样。5. 选型决策框架与落地建议5.1 按场景匹配方案选型没有绝对的对错只有合不合适。我整理了一个决策框架按场景来匹配如果你在做原型验证或者小规模项目数据量在百万以下团队没有专职运维pgvector是最省心的选择。你不需要新增任何基础设施用现有的PostgreSQL就能跑SQL接口学习成本几乎为零。如果你在做中等规模的生产项目数据量在百万到千万之间对过滤能力要求高Qdrant是最平衡的选择。它的部署简单过滤强大性能也好Rust写的稳定性有保障。如果你在做大规模项目数据量上亿需要水平扩展和多租户Milvus是首选。它的分布式架构能支撑很大的规模但需要Kubernetes和专职运维。如果你不想管运维预算充足Pinecone是最省事的。全托管服务按量付费但数据要放在它的云上成本随规模增长。5.2 迁移与扩展的注意事项从pgvector迁移到专用向量数据库是很多团队的路径。迁移的时候要注意pgvector的向量数据可以直接导出成CSV或者JSON然后批量导入新库。但索引需要重建不能直接迁移。另外pgvector的过滤条件是用SQL写的迁移到Qdrant或者Milvus需要改写成它们的过滤语法。扩展方面Milvus的扩展最灵活查询节点和数据节点可以独立扩。Qdrant的集群版也支持分片和副本但配置比Milvus简单。pgvector的扩展受限于PostgreSQL通常靠读写分离和分区表来扛。提示迁移之前一定要做性能对比测试用真实数据和真实查询模式跑一遍确认新方案在延迟、召回率、成本上都满足要求再切。5.3 成本估算的实操方法成本估算不能只看软件本身要把硬件、运维、人力都算进去。自建方案的成本主要是硬件和运维人力托管方案的成本主要是服务费。以Milvus为例1000万条768维向量的集群至少需要3个查询节点每个16核64GB、3个数据节点、3个etcd、3个MinIO。云上跑下来每月大概几千到上万元。Qdrant单机版如果内存够一台32核128GB的机器就能扛成本低很多。pgvector如果复用现有的PostgreSQL增量成本几乎为零。Pinecone的成本按pod算一个s1 pod每月约70美元能存约100万条768维向量。1000万条需要10个pod每月700美元左右。看起来不贵但查询量大了之后还有额外费用。5.4 团队技术栈的匹配最后说一个容易被忽略的点团队技术栈。如果团队是Python为主所有方案都有Python SDK问题不大。如果团队是JavaQdrant和Milvus都有Java客户端但pgvector需要通过JDBC写SQL稍微麻烦一点。如果团队是GoQdrant的Go客户端很成熟Milvus的Go SDK也在维护。另外如果团队已经在用KubernetesMilvus的Operator部署会很顺。如果团队没有K8sMilvus的运维成本会很高这时候Qdrant或者pgvector更合适。我在实际项目里的体会是选型的时候不要追求“最好”的方案要追求“最合适”的方案。一个团队用pgvector跑得很稳比用Milvus天天救火要好得多。向量数据库只是整个系统的一个组件它的稳定性、可维护性、和现有系统的集成成本往往比单纯的性能数字更重要。最后分享一个小技巧不管选哪个方案都先用真实数据做一次端到端的压测。压测的时候要模拟真实的查询模式包括过滤条件、并发数、批量大小。很多问题只有在真实负载下才会暴露出来提前发现比上线后救火强得多。
返回列表