加机器解决不了向量数据库的扩展问题
很多团队的认知是"向量数据库慢了→加机器→解决"。但实际上,向量数据库的扩展比传统数据库复杂得多。因为向量搜索天然是"全局"的——你需要在整个数据集中找到Top-K最相似的向量,而不仅仅是某个分片中的Top-K。
我们的RAG系统在18个月内,数据量从100万增长到10亿。中间经历了3次架构重构。以下是完整的演进过程。
第一阶段:单机Chroma(100万向量)
架构:Chroma嵌入式模式,单机MacBook Pro,数据存储在本地SSD。
这个阶段最简单。所有数据在单机上,HNSW索引常驻内存,查询延迟P99<20ms。当时觉得"向量数据库也不过如此"。
但单机有物理上限。 内存决定了最大索引大小,磁盘决定了最大存储容量,CPU决定了最大查询并发。当我们的数据量接近200万时,Chroma开始频繁OOM。
金句:单机方案的上限不是"数据量",而是"内存"。当你的索引大小超过可用内存的60%,就该考虑分布式了。
第二阶段:单机Milvus(1000万向量)
架构:一台AWS i4i.4xlarge(16核128GB RAM),Milvus单机部署。
从Chroma迁移到Milvus,性能提升显著。Milvus的C++引擎比Chroma的Python引擎快3-5倍。1000万向量下,P99延迟仍能保持在15ms左右。
但单机Milvus也有天花板:
- 存储上限:3.75TB NVMe SSD,约能存5亿条768维向量
- 内存上限:128GB RAM,约能存1.5亿条向量的索引
- 并发上限:单机Proxy处理约5000 QPS
金句:单机Milvus的极限是1-2亿向量。超过这个量级,你需要分布式。
第三阶段:Milvus分布式集群(5亿向量)
架构:8台i4i.4xlarge,Kubernetes部署,Milvus分布式模式。
这是最痛苦的一个阶段。Milvus的分布式架构包含8个微服务组件,每个组件都需要独立配置和监控。我们花了2个月才稳定运行。
关键架构决策:
- 分片策略:按tenant_id分片。每个租户的数据在同一个QueryNode上,避免跨节点查询。
- Proxy扩展:部署3个Proxy实例,前面加负载均衡,处理高并发。
- etcd高可用:3节点etcd集群,避免单点故障。
- 对象存储:使用S3存储持久化数据,QueryNode本地SSD做缓存。
分布式后,P99延迟从15ms升到了35ms(跨节点通信开销),但系统能稳定支持5亿向量,QPS达到10,000。
金句:分布式不是免费的午餐。它的代价是延迟增加、运维复杂度翻倍、故障排查难度指数级上升。
第四阶段:多集群+联邦查询(10亿向量)
当数据量接近10亿时,单集群的Milvus也出现了瓶颈——主要是etcd的元数据存储压力。我们采用了"多集群+联邦查询"的方案:
- 4个Milvus集群,每个管理2.5亿向量
- 联邦查询层:查询时并行搜索4个集群,合并Top-K结果
- 路由层:根据tenant_id路由到对应集群
这个架构的代价是:查询延迟增加到50-80ms(需要等待最慢的集群返回),但换来了近乎无限的扩展能力。
金句:10亿向量以上,没有现成的开源方案。你需要自己搭建联邦查询层。
扩展策略总结
| 数据量 | 架构 | 月成本 | P99延迟 | 运维复杂度 |
|---|---|---|---|---|
| <100万 | 单机Chroma/Qdrant | $0-100 | <10ms | 零 |
| 100万-5000万 | 单机Milvus | $500-1,000 | <20ms | 低 |
| 5000万-5亿 | Milvus集群 | $2,000-5,000 | <40ms | 中 |
| 5亿-10亿 | 多集群 | $5,000-15,000 | <100ms | 高 |
| >10亿 | 自研联邦 | 定制 | 定制 | 极高 |
金句:每个阶段之间的迁移成本不同。从单机到分布式是最大的跳跃,建议在数据量达到单机极限的50%时就开始规划迁移。