从一个痛点开始
想象一下这个场景:你正在构建一个RAG应用,需要从10亿份文档中找出与用户问题最相关的内容。传统数据库只能做精确匹配,无法理解语义------"苹果很好吃"和"iPhone 15值得买吗"在字面上毫无关系,但它们都与"苹果"这个实体相关。这就是向量数据库要解决的问题。
Qdrant(读作"quadrant")是一个用Rust编写的开源向量数据库,专为高可扩展、高可靠的向量相似度搜索而生。它的核心竞争力可以概括为三点:为向量搜索而生的专用架构、生产就绪的工程实现、以及对开发者体验的极致追求。
为什么需要一个专用的向量数据库?
你可能会问:"我能不能用PostgreSQL加上pgvector插件?" 答案是:可以,但不一定是最优解。
这就像问能不能用瑞士军刀砍柴------勉强能用,但效率和体验都不对。向量搜索有着独特的技术挑战:
1. 向量很重
一个1536维的OpenAI嵌入向量占用6KB存储空间。100万条记录就是6GB。如果再加上原始文本、JSON元数据,存储和访问的开销会迅速膨胀。
2. 向量搜索不是精确匹配
传统数据库的B-Tree索引对向量搜索几乎无效。你需要的是近似最近邻搜索------在99%的精度下换取1000倍的性能提升。这需要专门的索引结构。
3. 向量搜索对延迟极度敏感
用户不会等待3秒钟才看到搜索结果。向量搜索需要在毫秒级别内完成数十万次向量比对。
Qdrant从底层就是为这些挑战设计的。它的口号很直接:"Built for Vector Search"------不只是支持向量搜索,而是为向量搜索而生。
Qdrant的核心数据模型
理解Qdrant的数据模型是上手的第一步。它非常直观,只有三个核心概念:
Point(点)
Point是Qdrant中的基本单元,由三部分组成:
-
ID:唯一标识符(UUID或64位整数)
-
Vector:高维向量(稠密、稀疏或多向量)
-
Payload:可选的JSON元数据
{
"id": "doc_12345",
"vector": [0.1, 0.2, ..., 0.9], // 1536维
"payload": {
"title": "向量数据库入门",
"author": "张三",
"category": "technology",
"publish_date": "2025-01-15"
}
}
向量类型
Qdrant支持三种向量类型:
-
稠密向量:最常见的形式,每个维度都有值(非零),适合捕获语义相似性
-
稀疏向量 :大部分维度为0,用
(索引, 值)对表示,适合关键词搜索和BM25风格的检索 -
多向量:每个点关联多个向量,适合ColBERT等延迟交互模型
Collection(集合)
Collection类似于传统数据库的"表",是Point的容器。每个Collection需要指定向量配置:向量维度、距离度量(余弦相似度/点积/欧氏距离)等。
架构深潜:Qdrant是如何工作的?
索引:HNSW的工程化实现
Qdrant使用HNSW作为核心索引算法。HNSW构建了一个多层图结构:顶层稀疏,用于快速定位;底层稠密,用于精确搜索。这种结构让搜索复杂度从O(N)降到了O(log N)。
但HNSW有一个致命弱点:构建成本高,且随着数据量增长呈非线性增加。想象一下,每次插入新向量都要重建整个索引------这在生产环境是不可接受的。
Qdrant的解决方案是分段架构:
-
新数据先写入Mutable Segment(可变段),使用轻量级索引
-
当Segment达到阈值后,转换为Immutable Segment(不可变段),构建完整的HNSW索引
-
搜索时,并行查询所有Segment,合并结果
这种设计让Qdrant可以在索引构建的同时,不间断地服务查询请求。
过滤:向量搜索中的难点
向量搜索是模糊的------每个文档与查询都有不同程度的相似性。但当我们需要过滤时(比如"只搜索价格低于100元的商品"),问题就复杂了。
常见方案有两种,各有缺陷:
-
Pre-filtering:先过滤再搜索。如果过滤后只剩1%的数据,没问题;但如果过滤条件太宽松(比如"价格低于10000元"),你需要扫描整个数据集。
-
Post-filtering:先搜索再过滤。如果top-100结果都不符合过滤条件,你什么都得不到。
Qdrant的解决方案是Filterable HNSW:在构建索引时,将Payload中的过滤条件考虑进去。搜索时,在HNSW图遍历的过程中同步应用过滤条件,避免了两阶段方法的性能瓶颈。
分布式设计:BASE而非ACID
Qdrant在分布式设计上做了一个鲜明的选择:优先保证可用性,而不是强一致性。
根据CAP定理,分布式系统只能在Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性)中选择两个。网络分区是不可避免的,所以所有分布式系统都必须支持P。剩下的选择是C还是A。
Qdrant选择了BASE(Basically Available, Soft state, Eventually consistent)而非ACID。
这意味着什么?当你写入一个向量,可能不会立即在所有副本中可见,但系统会持续响应请求,最终达到一致状态。
这个选择是明智的。因为向量本质上是原始数据的"派生品"------如果数据丢失,可以从原始数据用相同的嵌入模型重新生成。牺牲强一致性换取高可用性,是合理的权衡。
快速上手:5分钟跑通Qdrant
方式一:Docker运行(推荐)
# 拉取并运行Qdrant
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd)/qdrant_storage:/qdrant/storage \
qdrant/qdrant
-
6333:REST API端口 -
6334:gRPC端口(性能更好)
方式二:Qdrant Cloud
访问Qdrant Cloud注册免费账号,获取托管实例。
方式三:Kubernetes
使用官方Helm Chart:
helm repo add qdrant https://qdrant.github.io/qdrant-helm
helm install qdrant qdrant/qdrant
Python客户端示例
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
import uuid
# 连接到Qdrant
client = QdrantClient(host="localhost", port=6333)
# 创建Collection
client.create_collection(
collection_name="my_books",
vectors_config=VectorParams(size=768, distance=Distance.COSINE),
)
# 插入向量
client.upsert(
collection_name="my_books",
points=[
PointStruct(
id=uuid.uuid4(),
vector=[0.1] * 768, # 真实场景中是嵌入向量
payload={"title": "AI Engineering", "author": "John Doe"}
)
]
)
# 搜索
results = client.search(
collection_name="my_books",
query_vector=[0.1] * 768, # 查询向量
limit=5,
query_filter=models.Filter(
must=[models.FieldCondition(key="author", match=models.MatchValue(value="John Doe"))]
)
)
应用场景
1. RAG应用
这是Qdrant最典型的应用场景。将文档分块并嵌入向量,用户查询时先检索最相关的段落,再交给LLM生成答案。Qdrant与LangChain、LlamaIndex等框架深度集成。
2. 语义搜索和推荐系统
电商平台的"猜你喜欢"、内容平台的"相关推荐",本质都是向量相似度搜索。Qdrant的Payload过滤功能特别适合电商场景------可以在语义搜索的同时,按价格、品牌、库存等条件过滤。
3. AI Agent的记忆系统
结合MCP(Model Context Protocol),Qdrant可以作为AI Agent的长期记忆存储。Agent可以将重要信息(代码片段、用户偏好、决策记录)向量化存储,后续会话中快速检索。
性能优化技巧
1. 选择合适的距离度量
-
Cosine:最常用,适合语义相似度
-
Dot:适合已经归一化的向量,性能略优于Cosine
-
Euclidean:适合空间距离计算
2. 使用量化压缩
Qdrant支持Scalar Quantization 和Binary Quantization,可以将内存占用降低4-8倍,同时保持95%以上的精度。
3. 配置HNSW参数
-
m:每个节点的最大连接数(默认16),越大召回率越高但内存越大 -
ef_construct:构建时的动态列表大小(默认100),越大索引质量越高但构建越慢
4. 批量写入
使用upsert批量插入,而不是逐条插入,可以减少网络往返和索引重建开销。
与其他向量数据库的对比
| 特性 | Qdrant | Pinecone | Milvus | Weaviate |
|---|---|---|---|---|
| 开源 | ✅ | ❌ | ✅ | ✅ |
| 语言 | Rust | - | Go/C++ | Go |
| 过滤能力 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 分布式 | ✅ | ✅ | ✅ | ✅ |
| 自托管 | ✅ | ❌ | ✅ | ✅ |
| 多向量 | ✅ | ❌ | ✅ | ❌ |
Qdrant的核心优势在于Rust的性能 和Filterable HNSW的过滤能力 。如果你需要复杂的元数据过滤,Qdrant是最佳选择-6。
总结:Qdrant适合你吗?
选择Qdrant,如果你:
-
需要高性能的向量搜索(毫秒级延迟)
-
有复杂的元数据过滤需求
-
希望用Rust的高性能但不想自己折腾底层
-
想要一个生产就绪的开源解决方案
考虑其他方案,如果你:
-
数据量很小(<10万条),pgvector足够
-
需要ACID事务(但向量搜索很少需要)
-
已经在用某云厂商的向量数据库生态
向量数据库的赛道正在快速演进,但Qdrant凭借其专注的架构设计 、优秀的工程实现 和活跃的开源社区,已经成为这个领域的领跑者之一。无论你是构建RAG应用、推荐系统,还是AI Agent,Qdrant都值得一试。