随着RAG(检索增强生成)和AI应用的普及,向量数据库成了很多团队的标配。我们团队也不例外,早在两年前就引入了向量数据库,用来做语义检索和知识库。
但随着数据量的增长和业务的发展,原来的向量数据库逐渐跟不上了。查询变慢、扩容困难、功能不够用,各种问题开始出现。于是,我们决定做一次向量数据库的选型和迁移。
这篇文章,就来分享这次向量数据库选型迁移的完整实战经历,包括需求分析、选型对比、迁移方案、踩过的坑和最终的效果。如果你也在考虑向量数据库的选型或者迁移,希望这篇文章能给你一些参考。
为什么要迁移
先说说为什么要迁移。
我们原来用的向量数据库,是一个比较轻量的开源方案。刚上线的时候,数据量只有几十万条,查询延迟在100毫秒以内,完全够用。
但两年下来,数据量增长到了几千万条,业务也从简单的语义检索,扩展到了多模态检索、推荐系统、实时分析等场景。原来的数据库开始出现各种问题:
第一个问题,查询性能下降。数据量超过一千万之后,查询延迟明显上升,从原来的100毫秒变成了500毫秒以上,高峰期甚至超过1秒。用户反馈搜索变慢了,体验很差。
第二个问题,扩容困难。原来的数据库是单机部署,扩容需要停机迁移,而且不支持水平扩展。数据量再增长下去,单机的磁盘和内存都扛不住了。
第三个问题,功能不够。原来的数据库只支持基本的向量相似度搜索,不支持标量过滤、混合查询、多租户、实时写入等高级功能。而我们的新业务,这些功能都需要。
第四个问题,运维成本高。原来的数据库社区不够活跃,文档不够完善,遇到问题很难找到解决方案。监控和备份工具也比较简陋,运维起来很费劲。
综合考虑之后,我们决定换一个更成熟、更强大的向量数据库。
需求分析
动手选型之前,我们先做了详细的需求分析。
功能需求:
- 支持向量相似度搜索,包括余弦相似度、内积、欧氏距离
- 支持标量过滤,能根据metadata过滤查询结果
- 支持混合查询,向量搜索和关键词搜索结合
- 支持实时写入和更新,数据写入后立即可查
- 支持多租户,不同业务的数据隔离
- 支持批量导入,方便历史数据迁移
- 支持持久化和备份,数据不丢失
性能需求:
- 数据量五千万条,向量维度1024维
- 查询延迟P99在200毫秒以内
- 支持每秒一万次查询的并发量
- 写入吞吐量每秒一千条以上
运维需求:
- 支持水平扩展,能在线扩容
- 有完善的监控和告警
- 有成熟的备份和恢复方案
- 社区活跃,文档完善,有商业支持
成本需求:
- 总体拥有成本可控,包括软件成本、硬件成本、运维成本
- 最好是开源的,可以自主部署和定制
把这些需求整理清楚之后,我们就开始了选型。
选型对比
我们调研了市面上主流的向量数据库,主要对比了这几个:Milvus、Qdrant、Weaviate、Pinecone、pgvector。
Milvus:
- 优点:功能强大,支持各种索引类型和查询方式;分布式架构,水平扩展能力强;社区活跃,文档完善;有商业支持(Zilliz)
- 缺点:部署和运维比较复杂,组件多;资源消耗较大;学习曲线较陡
- 适合:大规模、高并发、复杂查询场景
Qdrant:
- 优点:性能优秀,查询延迟低;Rust编写,内存占用小;部署简单,单二进制文件;API设计友好;支持标量过滤和混合查询
- 缺点:分布式功能相对较新,大规模集群的稳定性还需要验证;社区比Milvus小一些
- 适合:中大规模、追求性能和简单部署的场景
Weaviate:
- 优点:内置向量化模块,不需要单独部署embedding服务;支持GraphQL查询;有丰富的模块生态;文档友好
- 缺点:性能不如Milvus和Qdrant;资源消耗较大;定制化能力有限
- 适合:快速原型、中小规模、需要内置向量化的场景
Pinecone:
- 优点:全托管服务,零运维;性能稳定,扩展性好;支持丰富的功能
- 缺点:闭源,成本高;数据在第三方,有隐私和合规风险;不能自主部署
- 适合:不想自己运维、预算充足的团队
pgvector:
- 优点:基于PostgreSQL,学习成本低;和关系型数据无缝集成;部署简单;事务支持好
- 缺点:性能不如专门的向量数据库,大数据量下查询慢;扩展能力有限;高级功能少
- 适合:小规模、已经在用PostgreSQL、向量查询不是核心场景的团队
我们的场景是:数据量五千万条,高并发查询,需要标量过滤和混合查询,需要自主部署,运维成本可控。
综合对比之后,我们最终选择了Qdrant。主要原因是:
- 性能优秀,查询延迟低,能满足我们的性能需求
- 部署简单,单二进制文件,运维成本低
- 支持标量过滤、混合查询、多租户等我们需要的功能
- Rust编写,内存占用小,硬件成本低
- 社区活跃,发展速度快
Milvus虽然功能更强大,但部署和运维太复杂,我们团队没有足够的人力去维护。Pinecone虽然省心,但成本太高,而且有数据隐私的顾虑。pgvector性能不够,满足不了我们的需求。
迁移方案
选定了Qdrant之后,我们开始设计迁移方案。
迁移的最大挑战是:不能停机。我们的业务是7x24小时运行的,不能因为迁移而中断服务。所以,我们采用了"双写+灰度切换"的方案。
第一步,搭建新的Qdrant集群。我们用三台服务器搭建了Qdrant集群,配置了持久化存储和备份。同时,搭建了监控和告警,确保新集群的稳定运行。
第二步,数据全量迁移。我们写了一个迁移脚本,从旧数据库中读取所有数据,转换成Qdrant的格式,批量导入Qdrant。全量迁移花了大约六个小时,迁移了五千万条数据。迁移过程中,我们做了数据校验,确保数据的完整性和一致性。
第三步,双写。全量迁移完成之后,我们开启了双写模式:新数据同时写入旧数据库和Qdrant。这样,在迁移期间,两个数据库的数据保持一致。双写持续了一周,期间我们不断对比两个数据库的查询结果,确保一致性。
第四步,灰度切换。双写稳定运行一周之后,我们开始灰度切换。先把10%的查询流量切到Qdrant,观察性能和稳定性。没有问题之后,逐步增加到30%、50%、100%。整个灰度过程持续了三天。
第五步,停写旧数据库。全部流量切到Qdrant之后,我们停止了对旧数据库的写入,但保留旧数据库作为只读备份,持续了两周。确认没有问题之后,正式下线旧数据库。
整个迁移过程,从搭建新集群到下线旧数据库,持续了将近一个月。虽然时间比较长,但整个过程非常平稳,用户完全没有感知到迁移。
踩过的坑
迁移过程中,我们也踩了不少坑,这里分享几个典型的。
第一个坑,向量维度不一致。我们原来的数据库用的是768维的向量,新业务想用1024维的向量。一开始我们想直接在Qdrant中混用不同维度的向量,但Qdrant的一个collection只能有一种向量维度。解决方案是:建两个collection,一个存768维的旧数据,一个存1024维的新数据,查询的时候根据数据来源选择对应的collection。
第二个坑,标量过滤的性能。Qdrant的标量过滤功能很强大,但如果过滤条件太复杂,或者过滤后的结果集太大,查询性能会明显下降。我们一开始把所有的metadata都建了索引,结果索引占用了大量内存,查询反而变慢了。后来,我们只对常用的过滤字段建索引,并且优化了过滤条件,性能才恢复正常。
第三个坑,批量导入的速度。全量迁移的时候,我们一开始用的是单线程导入,速度很慢,五千万条数据估计要导入两天。后来,我们改成了多线程并发导入,并且调整了Qdrant的写入参数(比如关闭实时索引、增大写入缓冲区),导入速度提升了五倍,六个小时就完成了。
第四个坑,数据一致性。双写期间,我们发现偶尔会出现两个数据库数据不一致的情况。原因是旧数据库写入成功但Qdrant写入失败,或者反过来。解决方案是:增加了一个对账任务,每天定时对比两个数据库的数据,发现不一致就自动修复。同时,写入的时候加了重试机制,确保写入成功。
第五个坑,监控指标不熟悉。Qdrant的监控指标和旧数据库不一样,一开始我们不知道该看哪些指标,出了问题不能及时发现。后来,我们仔细研究了Qdrant的文档,配置了关键指标的告警,包括查询延迟、写入延迟、内存使用、磁盘使用、集群状态等,才建立起完善的监控体系。
这些坑,虽然给我们带来了一些麻烦,但也让我们对Qdrant有了更深的理解。
迁移后的效果
迁移完成之后,效果非常明显。
性能方面:
- 查询延迟P99从原来的500毫秒以上,降到了80毫秒以内
- 并发查询能力从原来的每秒两千次,提升到了每秒一万五千次
- 写入吞吐量从原来的每秒两百条,提升到了每秒三千条
功能方面:
- 支持了标量过滤,查询结果可以按时间、分类、权限等过滤
- 支持了混合查询,向量搜索和关键词搜索结合,搜索准确率提升了30%
- 支持了多租户,不同业务的数据完全隔离,安全性大大提升
- 支持了实时写入,数据写入后立即可查,延迟在10毫秒以内
运维方面:
- 水平扩展方便,增加节点只需要几分钟,不需要停机
- 监控完善,出了问题能及时发现和定位
- 备份恢复简单,每天自动备份,恢复时间在半小时以内
成本方面:
- 硬件成本降低了,因为Qdrant内存占用小,原来需要三台高配置服务器,现在三台普通配置就够了
- 运维成本降低了,部署和维护都比原来简单
- 总体拥有成本比原来降低了约40%
用户反馈也很好,搜索速度变快了,搜索结果更准确了,新功能也能更快地上线了。
一些经验和建议
基于这次迁移的经验,给想做向量数据库选型或迁移的团队一些建议。
第一,需求先行。不要盲目追求功能强大或者性能顶尖的数据库,先搞清楚自己的需求。数据量多大、查询并发多少、需要哪些功能、预算多少、运维能力如何,这些都要想清楚。适合自己的,才是最好的。
第二,充分测试。选型的时候,一定要用自己的真实数据做测试。不要只看官方的benchmark,因为不同的数据分布和查询模式,性能差异很大。把候选数据库都部署起来,用自己的数据跑一遍,对比性能、功能、易用性。
第三,制定详细的迁移方案。迁移不是小事,一定要有详细的方案,包括全量迁移、增量同步、灰度切换、回滚方案等。特别是不能停机的业务,一定要设计好双写或者增量同步的方案,确保迁移过程中业务不中断。
第四,做好数据校验。迁移过程中,数据一致性是最重要的。一定要有数据校验机制,全量迁移之后要校验,双写期间要定期对账,确保两个数据库的数据一致。
第五,灰度切换。不要一次性把所有流量切到新数据库,要灰度切换,从小流量开始,逐步增加。观察性能、稳定性、错误率,没有问题再继续增加。一旦发现问题,随时可以切回去。
第六,保留回滚能力。迁移期间,一定要保留回滚的能力。如果新数据库出了问题,能快速切回旧数据库。不要急着下线旧数据库,等新数据库稳定运行一段时间之后再下线。
第七,文档和培训。迁移完成之后,要及时更新文档,包括架构图、运维手册、故障处理指南等。同时,对团队成员进行培训,让大家熟悉新数据库的使用和运维。
写在最后
这次向量数据库的选型和迁移,是我们团队今年做的比较有价值的一个项目。
它不仅解决了原来的性能和功能问题,也让我们对向量数据库有了更深的理解。更重要的是,我们积累了一套数据库迁移的方法论,以后再做类似的迁移,就有经验可循了。
向量数据库是AI时代的基础设施,随着AI应用的发展,它会越来越重要。选择一个合适的向量数据库,并且做好迁移和运维,对AI应用的稳定性和性能至关重要。
希望这次实战的经验,能给大家一些参考。如果你也在做向量数据库的选型或者迁移,欢迎交流分享。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录