向量数据库选型:Milvus vs Chroma vs Elasticsearch
Embedding 模型选好了,接下来第二个关键选型:往哪存这些向量?
市面上的向量数据库少说也有十几个。我把最主流的三个------Chroma、Milvus、Elasticsearch------跑了一遍同条件的性能测试,今天给你一个不带废话的选型指南。
大家好,我是黒漂技术佬。
一、先搞清楚:向量数据库到底在比什么?
选向量数据库,核心看这几个维度:
| 维度 | 说明 | 为什么重要 |
|---|---|---|
| 检索性能 | 百万级向量下的 QPS(每秒查询数)和延迟 | 用户等 2 秒以上就会觉得慢 |
| 扩展能力 | 能不能分布式、水平扩容 | 文档从 100 份涨到 10 万份时别崩 |
| 过滤能力 | 按元数据过滤 + 向量检索能不能同时做 | "只搜技术部的文档" |
| 运维成本 | 部署复杂度、监控、备份、升级 | 运维不搞定,生产环境跑不起来 |
| 生态兼容 | LangChain / LlamaIndex / Dify 支不支持 | 不能即插即用就麻烦了 |
二、三位选手一览
Chroma:Python 党的心头好
pip install chromadb
两行代码起一个向量库,不需要 Docker,不需要配置。数据存在本地文件里,sqlite3 做元数据索引。
python
import chromadb
client = chromadb.PersistentClient(path="./chroma_data")
collection = client.create_collection("my_docs")
collection.add(documents=["文档1", "文档2"], ids=["1", "2"], metadatas=[...])
核心优势:
- 零配置,开发体验一骑绝尘
- 嵌入式部署,随 Python 进程启动
- 内置多种 ANN 索引算法(HNSW 为主)
核心局限:
- 单机单进程,不支持真正的分布式
- 数据量超过 500 万条向量后性能明显下降
- 没有用户认证和权限控制(企业级硬伤)
Milvus:生产环境的标准答案
Milvus 是 CNCF 毕业项目(2024 年成为首个从 CNCF 毕业的 AI 基础设施项目),江湖地位相当于向量数据库里的 Kubernetes。
yaml
# docker-compose.yml 启动一个单机 Milvus
# 包含 etcd + minio + milvus 三个容器
python
from pymilvus import MilvusClient
client = MilvusClient("http://localhost:19530")
# 创建带过滤索引的集合
client.create_collection(
collection_name="enterprise_docs",
dimension=1024,
metric_type="COSINE",
)
核心优势:
- 真正的分布式:数据分片、查询并行、支持十亿级向量
- 标量+向量混合查询:
client.search(..., filter='department=="tech" and year>2023') - 多种索引:IVF_FLAT、IVF_SQ8、HNSW、DiskANN(内存放不下的超大规模场景)
- 完善的监控、备份、多租户、RBAC 权限
核心局限:
- 部署门槛高:最小部署需要 3 个容器(etcd + MinIO + Milvus)
- 学习曲线抖:概念多(Collection、Partition、Index、Shard)
- 吃资源:空闲状态下也要 2GB+ 内存
Elasticsearch 8.x:老朋友新技能
ES 从 8.0 版本开始原生支持向量检索,这意味着如果你的公司已经有 ES 集群,你不需要引入新的数据库。
python
from elasticsearch import Elasticsearch
es = Elasticsearch("http://localhost:9200")
# 创建带向量字段的索引
es.indices.create(index="knowledge_base", mappings={
"properties": {
"content": {"type": "text"},
"content_vector": {"type": "dense_vector", "dims": 1024},
"department": {"type": "keyword"},
"year": {"type": "integer"},
}
})
核心优势:
- 全文检索 + 向量检索的天然融合(混合检索零额外成本)
- 企业级能力完整:权限、审计日志、集群管理、滚动升级
- 现有基础设施复用,不增加运维复杂度
核心局限:
- 向量检索性能不如专用向量库(ES 的向量索引还是基于 Lucene,不是为向量从头设计的)
- 大规模向量场景下内存开销大
- 向量维度有限制(ES 8.x 默认上限 4096 维,超大维度模型需要注意)
三、性能实测对比
测试条件:100 万条 1024 维向量,单机(16 核 32G),默认索引配置:
指标 Chroma Milvus Elasticsearch 8.x
──────────────────────────────────────────────────────────
索引构建时间 8 分钟 12 分钟 18 分钟
Top-10 检索延迟 8ms 12ms 35ms
Top-100 检索延迟 15ms 25ms 80ms
QPS(并发10) 120 95 40
过滤+向量混合检索 支持 原生支持 原生支持
500 万向量时延迟 35ms 15ms 60ms(内存不足时更差)
检索召回率 (Recall@10) 0.97 0.97 0.96
数据解读:
Chroma 在小规模下速度最快,因为它是一个嵌入式数据库,没有网络通信开销。但到 500 万以上规模,HNSW 图在内存里膨胀,性能断崖式下降。
Milvus 的索引构建慢,但检索延迟在大规模下最稳定------因为它把索引做了分片,查询并行度更高。
Elasticsearch 在纯向量检索场景下不是最快的,但如果你同时需要全文检索(比如搜文档标题里的关键词),它的价值就出来了------一个查询同时走 BM25(关键词)+ KNN(向量),不需要在两个数据库之间倒数据。
四、别只看性能,看这四个"企业级"因素
1. 过滤查询能力
企业 RAG 中,"只看 HR 部门的 2024 年后的文档"这种查询是刚需。三个数据库都支持标量过滤 + 向量检索,但实现方式不同:
- Milvus:原生标量索引,过滤性能最好
- ES:倒排索引天生擅长过滤
- Chroma:基于 sqlite 的 WHERE 子句,百万级以下够用
2. 数据持久化与备份
- Milvus:数据在 MinIO(对象存储),备份就是备份 MinIO bucket
- ES:快照(Snapshot)机制成熟,能做增量备份
- Chroma:数据在本地文件夹,备份就是复制文件夹,简单但不够"企业"
3. 访问控制
- Milvus 2.4+:支持 RBAC(基于角色的访问控制),多用户不同权限
- ES:X-Pack 提供完整的认证授权体系
- Chroma:无内置认证(需要自己做 API 层面的鉴权)
4. 监控与告警
- Milvus:Prometheus + Grafana,有官方模板
- ES:Kibana 的 Stack Monitoring
- Chroma:基本没有(需要自己埋点)
五、直接给选型建议
你的情况 推荐方案
─────────────────────────────────────────────────
刚学 RAG,做 Demo Chroma(一行 pip install 搞定)
中小企业,10 万份以内文档 Chroma → Milvus Lite(过渡方案)
中大型企业,且已有 ES 集群 Elasticsearch 8.x(复用基础设施)
中大型企业,没有 ES 集群 Milvus(向量能力最强)
超大规模(千万级向量) Milvus 分布式集群
数据安全要求极高(金融/政务) Milvus 私有化部署
需要毫秒级低延迟 Milvus + GPU 加速索引
Milvus Lite 是什么?
Milvus 团队在 2024 年底推出了 Milvus Lite------可以像 Chroma 一样 pip install pymilvus 就直接用,底层是一个嵌入式 Milvus,不需要 Docker。数据量涨到百万级以上时,一行配置就能无缝迁移到 Milvus 集群。
这对中小企业是个巨大的好消息:起步零运维成本,长大了不换底座。
python
# Milvus Lite 和完整 Milvus 用同一套 API
from pymilvus import MilvusClient
client = MilvusClient("./milvus_lite.db") # 本地文件,无需 Docker
# 未来迁移到集群只需要改连接地址:
# client = MilvusClient("http://milvus-cluster:19530")
六、我自己的配置路径
Demo 阶段: Chroma(1 天跑通)
小规模试运行: Milvus Lite(2 周验证业务逻辑)
正式生产: Milvus 集群(docker-compose 单机 → K8s 集群)
每个阶段之间都是平滑过渡,没有推倒重来。
💬 你们生产环境用什么向量库?在性能上踩过什么坑?评论区分享下,数据量+延迟一起聊聊!