GitHub: qdrant/qdrant
Stars: 32,300+ | Language: Rust (87.3%) | License: Apache 2.0
官网: qdrant.tech | 最新版本: v1.18.2 (2026-06-04)
目录
- 项目速览
- 功能概述
- 适用场景
- 快速上手
- 源码架构
- 实操 Demo
- 同类对比
- 参考资源
项目速览
Qdrant 由德国团队于 2021 年开源,使用 Rust 语言从头构建,是目前性能最高的向量数据库之一。截至 2026 年 6 月,项目在 GitHub 上已获得超过 32,300 颗 Star,最新版本为 v1.18.2。Qdrant 同时提供 Qdrant Cloud 托管服务和 Qdrant Edge(嵌入式边缘计算版本)。
Qdrant 在工程层面极具特色:它是少有的纯 Rust 编写的数据库,充分利用了 Rust 的零成本抽象、内存安全和极致性能优势。底层使用 io_uring 实现异步 I/O、SIMD 指令加速向量计算,GPU 支持覆盖 NVIDIA 和 AMD 两大平台。在向量量化方面,Qdrant 的产品量化(Product Quantization)可将内存占用降低高达 97%,同时通过磁盘存储(on-disk storage)支持将索引卸载到 SSD,实现了内存成本与检索性能之间的灵活权衡。
Qdrant v1.18 版本进一步增强了混合检索能力,引入基于分布的分值融合(Distribution-Based Score Fusion,DBSF),在 Reciprocal Rank Fusion(RRF)基础上提供了更精细的融合策略。
功能概述
多向量搜索:稠密、稀疏与多向量
Qdrant 支持三种向量检索模式:
- 稠密向量:传统的 Embedding 向量(如 text-embedding-3-small 输出的 1536 维浮点向量)
- 稀疏向量:BM25、SPLADE 等生成的稀疏编码向量,适用于关键词精确匹配
- 多向量(Multi-Vector):一个数据点可关联多个向量(如 ColBERT 的 token 级多向量表示),实现 Late Interaction 检索
这三种模式可在同一集合中共存,通过 target_vector 参数在查询时按名称选择。
高级 Payload 过滤
Qdrant 的 Payload(附加数据)过滤系统极其强大,支持 JSON 格式的任意结构化数据,过滤条件覆盖:
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
models.Filter( must=[ models.FieldCondition(key="price", range=models.Range(gte=100, lte=500)), models.FieldCondition(key="city", match=models.MatchValue(value="Beijing")) ] )
models.Filter( must=[ models.FieldCondition( key="location", geo_radius=models.GeoRadius(center=models.GeoPoint(lon=116.4, lat=39.9), radius=10000) ) ] )
|
支持的操作包括:等值匹配、范围查询、地理半径、全文匹配、数组包含、嵌套对象过滤、计数条件和 is_empty/is_null 检查。
混合检索:RRF 与 DBSF 融合
Qdrant 支持将稠密向量检索和稀疏关键词检索的结果进行融合:
- RRF(Reciprocal Rank Fusion):对两路结果的排名取倒数求和,简单高效
- DBSF(Distribution-Based Score Fusion):基于分值分布的统计融合,在分值分布差异较大时表现更优
融合策略可通过 fusion 参数灵活配置,并支持 auto_limit(自动截断低分值结果)减少噪音。
向量量化与磁盘存储
Qdrant 提供业界领先的向量量化方案,兼顾内存效率与检索精度:
| 量化方式 |
内存节省 |
精度影响 |
| Scalar Quantization (SQ) |
4x |
极低 |
| Product Quantization (PQ) |
高达 32x(97%) |
低至中等 |
| Binary Quantization (BQ) |
32x |
中等 |
此外,Qdrant 支持将量化后的向量索引存储在磁盘上(on-disk storage),通过 mmap 按需加载,实现内存使用量与检索延迟之间的精细控制。
Qdrant Edge — 嵌入式边缘部署
Qdrant Edge 是专门为资源受限环境设计的嵌入式版本,可直接编译为 WASM 运行在浏览器中,或嵌入到移动端和 IoT 设备上。API 与标准 Qdrant 保持兼容:
from qdrant_edge import Distance, EdgeConfig, EdgeVectorParams, EdgeShard, Point, UpdateOperation
shard = EdgeShard.create("./my_shard", EdgeConfig( vectors={"content": EdgeVectorParams(size=768, distance=Distance.Cosine)} ))
shard.update(UpdateOperation.upsert_points([ Point(id=1, vector={"content": [0.1] * 768}, payload={"title": "Edge Computing"}) ]))
|
适用场景
高性能实时检索
Qdrant 的 Rust 核心和 SIMD 优化使其在低延迟场景中表现出色。对于实时推荐系统、在线广告匹配和搜索引擎(<10ms 延迟要求),Qdrant 是极佳选择。io_uring 异步 I/O 在高并发场景下可显著降低系统调用开销。
内存受限的成本优化
对于需要在有限内存中存储海量向量的场景(如边缘设备、个人开发者云服务器),Qdrant 的量化机制(97% 内存节省)和磁盘索引可大幅降低硬件成本。在 8GB RAM 的云服务器上即可流畅运行亿级向量检索。
电商与本地生活搜索
Qdrant 的 Payload 过滤系统天然适配电商和本地生活场景:在向量语义相似度检索的同时,通过地理位置过滤(geo_radius)匹配附近商家,通过数值范围过滤(price range)筛选预算,通过全文匹配(keyword)满足品牌精确搜索需求。
多模态搜索
图片、文本、音频等多模态数据可分别以不同的向量名存储在同一数据点中。使用 CLIP 生成的图片向量和文本向量分别存入 image_vector 和 text_vector 字段,在查询时按需选择目标向量名,实现图文互搜。
AI Agent 记忆与上下文
Qdrant 的 Payload 灵活性使其适合作为 AI Agent 的记忆存储。Agent 的每次推理过程、工具调用结果和用户偏好都可以向量化后存入 Qdrant,Payload 中记录时间戳、会话 ID、置信度等元数据,通过语义检索 + 元数据筛选快速召回相关记忆。
快速上手
环境要求
- Docker(推荐用于服务端模式)
- Python 3.8+
安装
服务端模式:
docker run -p 6333:6333 -v $(pwd)/qdrant_storage:/qdrant/storage qdrant/qdrant
|
Python 客户端:
pip install qdrant-client
|
最简示例
from qdrant_client import QdrantClient from qdrant_client.models import Distance, VectorParams, PointStruct
client = QdrantClient(url="http://localhost:6333")
client.create_collection( collection_name="quickstart", vectors_config=VectorParams(size=384, distance=Distance.COSINE) )
client.upsert( collection_name="quickstart", points=[ PointStruct(id=1, vector=[0.05] * 384, payload={"text": "Qdrant is a vector search engine", "source": "docs"}), PointStruct(id=2, vector=[0.02] * 384, payload={"text": "Python is a programming language", "source": "wiki"}), PointStruct(id=3, vector=[0.08] * 384, payload={"text": "Vector databases power modern AI search", "source": "blog"}), ] )
hits = client.search( collection_name="quickstart", query_vector=[0.06] * 384, limit=2 )
for hit in hits: print(f"ID={hit.id}, score={hit.score:.4f}, text={hit.payload['text']}")
|
带过滤的搜索
from qdrant_client.models import Filter, FieldCondition, MatchValue
hits = client.search( collection_name="quickstart", query_vector=[0.06] * 384, query_filter=Filter( must=[FieldCondition(key="source", match=MatchValue(value="docs"))] ), limit=3 )
|
批量 upsert 推荐
batch_size = 100 for i in range(0, len(points), batch_size): batch = points[i:i + batch_size] client.upsert(collection_name="large_collection", points=batch)
|
源码架构
Qdrant 采用纯 Rust monorepo 结构,代码组织清晰:
qdrant/ ├── src/ # 核心服务端代码 │ ├── main.rs # 启动入口 │ ├── common/ # 通用数据结构与工具 │ ├── collection/ # 集合管理(CRUD、分片分配) │ ├── operations/ # 操作类型定义(Point/Vector/Upsert/Delete) │ ├── segment/ # 数据段:向量索引、Payload 索引、存储引擎 │ │ ├── index/ # 向量索引实现(HNSW) │ │ ├── payload_index/ # Payload 结构化索引 │ │ └── vector_storage/ # 向量存储(内存/mmap) │ ├── shards/ # 分片管理:本地分片、远程分片、副本同步 │ ├── consensus/ # Raft 共识协议实现 │ ├── api/ # REST + gRPC API 定义与处理 │ ├── storage/ # 底层存储抽象 │ └── quantization/ # 量化算法(Scalar/Product/Binary) ├── lib/ # 公共库 │ ├── api/ # API 类型定义 │ ├── collection/ # 集合共享类型 │ ├── segment/ # 数据段类型与工具 │ ├── storage/ # 统一存储接口 │ └── common/ # 基础类型与工具 ├── config/ # 默认配置文件 ├── docs/ # 文档 ├── openapi/ # OpenAPI 3.0 规范 ├── tests/ # 集成测试 ├── tools/ # 运维工具 └── Cargo.toml # Rust 构建配置
|
- **src/consensus/**:Qdrant 分布式模式的基石——基于 Raft 协议的集群共识层,负责节点间状态同步和 Leader 选举。
- **src/segment/**:数据持久化与检索的核心。每个 segment 是一个自包含的存储单元,包含向量索引(HNSW)、Payload 索引(支持全文/范围/地理等过滤加速)和原始向量存储。
- **src/quantization/**:向量量化实现。Scalar Quantization 将 float32 映射为 uint8,Product Quantization 分解为子向量码本,Binary Quantization 进一步压缩为 bit 表示。
- **src/collection/**:集合生命周期管理,包括创建、删除、别名管理,以及从 WAL 恢复到最终一致性的完整流程控制。
- **lib/ vs src/**:
lib/ 目录存放的是可被其他 Rust 项目引用的公共库类型,src/ 是和 Qdrant 服务端紧密绑定的业务逻辑。这种分离使得第三方 Rust 应用可以直接依赖 lib/ 包来构建自定义的 Qdrant 集成。
实操 Demo
以下是一个结合语义搜索与地理位置过滤的餐厅推荐 Demo:
""" 餐厅推荐 Demo:语义搜索 + 地理位置过滤 """ from qdrant_client import QdrantClient from qdrant_client.models import ( Distance, VectorParams, PointStruct, Filter, FieldCondition, Range, GeoRadius, GeoPoint ) import numpy as np
client = QdrantClient(url="http://localhost:6333")
print("[1/4] 正在创建集合...") client.create_collection( collection_name="restaurants", vectors_config=VectorParams( size=128, distance=Distance.COSINE, on_disk=True, quantization_config=models.ScalarQuantization( scalar=models.ScalarQuantizationConfig( type=models.ScalarType.INT8, always_ram=True ) ) ) )
print("[2/4] 正在插入餐厅数据...") np.random.seed(42) restaurants = [ PointStruct(id=1, vector=np.random.randn(128).tolist(), payload={"name": "老北京炸酱面馆", "cuisine": "中餐", "price": 45, "location": {"lon": 116.397, "lat": 39.908}}), PointStruct(id=2, vector=np.random.randn(128).tolist(), payload={"name": "Tokyo Sushi Bar", "cuisine": "日料", "price": 180, "location": {"lon": 116.404, "lat": 39.915}}), PointStruct(id=3, vector=np.random.randn(128).tolist(), payload={"name": "Paris Bistro", "cuisine": "法餐", "price": 350, "location": {"lon": 116.385, "lat": 39.903}}), PointStruct(id=4, vector=np.random.randn(128).tolist(), payload={"name": "Sichuan Hot Pot", "cuisine": "中餐", "price": 120, "location": {"lon": 116.410, "lat": 39.920}}), PointStruct(id=5, vector=np.random.randn(128).tolist(), payload={"name": "Ramen House", "cuisine": "日料", "price": 65, "location": {"lon": 116.391, "lat": 39.912}}), PointStruct(id=6, vector=np.random.randn(128).tolist(), payload={"name": "Italian Kitchen", "cuisine": "意大利菜", "price": 200, "location": {"lon": 116.398, "lat": 39.905}}), ] client.upsert(collection_name="restaurants", points=restaurants) print(f" 已插入 {len(restaurants)} 家餐厅")
print("[3/4] 正在执行复合搜索...") query_vec = np.random.randn(128).tolist()
print("\n=== 纯语义搜索(无过滤)===") results = client.search(collection_name="restaurants", query_vector=query_vec, limit=3) for hit in results: p = hit.payload print(f" {p['name']:20s} | {p['cuisine']:10s} | Y{p['price']} | score={hit.score:.4f}")
print("\n=== 语义 + 价格 ≤150 + 距离 5km ===") results = client.search( collection_name="restaurants", query_vector=query_vec, query_filter=Filter( must=[ FieldCondition(key="price", range=Range(lte=150)), FieldCondition( key="location", geo_radius=GeoRadius(center=GeoPoint(lon=116.397, lat=39.908), radius=5000) ) ] ), limit=5 ) for hit in results: p = hit.payload print(f" {p['name']:20s} | {p['cuisine']:10s} | Y{p['price']} | score={hit.score:.4f}")
print("\n[4/4] 清理中...") client.delete_collection("restaurants") print("Demo 完成!")
|
运行前提:
docker run -p 6333:6333 qdrant/qdrant
pip install qdrant-client numpy
|
同类对比
| 特性 |
Qdrant |
Milvus |
Chroma |
Weaviate |
| Stars |
32,300+ |
44,800+ |
28,400+ |
16,300+ |
| 核心语言 |
Rust |
Go + C++ |
Rust |
Go |
| 量化方案 |
SQ/PQ/BQ(节省 97%) |
PQ/SQ |
无内置 |
PQ/BQ/SQ |
| Payload 过滤 |
极强:范围/地理/全文/嵌套 |
Filter 表达式 |
where 过滤 |
where 过滤 |
| 混合检索 |
RRF + DBSF |
BM25/SPLADE 原生 |
Chroma Cloud 支持 |
BM25 + 向量 |
| GPU 加速 |
NVIDIA + AMD |
NVIDIA CAGRA |
无 |
无 |
| 嵌入式部署 |
Qdrant Edge (WASM) |
Milvus Lite |
嵌入式 |
嵌入式 |
| 分布式共识 |
Raft |
Pulsar/Kafka 消息队列 |
无(单节点) |
Raft |
| API 协议 |
REST (OpenAPI) + gRPC |
gRPC + REST |
Python/JS SDK |
GraphQL + REST + gRPC |
| 部署复杂度 |
低至中 |
中高 |
极低 |
中等 |
| 学习曲线 |
低至中 |
中高 |
极低 |
中等 |
分析:Qdrant 在性能和易用性之间找到了出色的平衡点。它的 Rust 核心提供了接近 C++ 级别的性能,同时 Payload 过滤系统的灵活性远超其他向量数据库。量化方案(节省 97% 内存)和 on-disk 存储体现了务实的产品设计理念。Qdrant Edge 的 WASM 嵌入式方案更是一大亮点,将向量检索能力延伸到了浏览器和 IoT 设备中。如果你的场景需要在向量语义检索的同时进行复杂的结构化过滤(如地理位置、价格区间、多条件组合),Qdrant 的 Payload 系统无可匹敌。对于纯向量检索且追求极致简单,Chroma 更胜一筹;对于千亿级的超大规模集群,Milvus 的生态更成熟。
参考资源