向量数据库选型:Milvus vs Chroma vs Elasticsearch

Embedding 模型选好了,接下来第二个关键选型:往哪存这些向量?

市面上的向量数据库少说也有十几个。我把最主流的三个——Chroma、Milvus、Elasticsearch——跑了一遍同条件的性能测试,今天给你一个不带废话的选型指南。

大家好,我是黒漂技术佬。


一、先搞清楚:向量数据库到底在比什么?

选向量数据库,核心看这几个维度:

维度 说明 为什么重要
检索性能 百万级向量下的 QPS(每秒查询数)和延迟 用户等 2 秒以上就会觉得慢
扩展能力 能不能分布式、水平扩容 文档从 100 份涨到 10 万份时别崩
过滤能力 按元数据过滤 + 向量检索能不能同时做 “只搜技术部的文档”
运维成本 部署复杂度、监控、备份、升级 运维不搞定,生产环境跑不起来
生态兼容 LangChain / LlamaIndex / Dify 支不支持 不能即插即用就麻烦了

二、三位选手一览

Chroma:Python 党的心头好

pip install chromadb

两行代码起一个向量库,不需要 Docker,不需要配置。数据存在本地文件里,sqlite3 做元数据索引。

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。

# docker-compose.yml 启动一个单机 Milvus
# 包含 etcd + minio + milvus 三个容器
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 集群,你不需要引入新的数据库。

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 集群。

这对中小企业是个巨大的好消息:起步零运维成本,长大了不换底座。

# 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 集群)

每个阶段之间都是平滑过渡,没有推倒重来。


💬 你们生产环境用什么向量库?在性能上踩过什么坑?评论区分享下,数据量+延迟一起聊聊!

更多推荐