Qdrant 是一个用 Rust 编写的开源向量数据库,提供向量相似度检索、payload 元数据过滤、分布式分片与副本等生产级能力。它解决的问题很具体:当 RAG、语义搜索、推荐召回需要在上亿向量中做「语义最相似」查询,同时还要按业务字段(用户、部门、类目、价格)过滤时,Elasticsearch 的关键词匹配无法覆盖语义相似,而 FAISS 这类算法库又缺少持久化、过滤与多语言 API。Qdrant 把「近似最近邻检索 + 业务过滤 + 持久化存储」合体现在一个服务里,以 REST/gRPC 接口对外提供,并配套 Python、Go、TypeScript 等官方 SDK。它的设计主线是从「可用的向量检索引擎」逐步演进为「搜索与过滤并重的生产级向量数据库」,这也是它与 Milvus、Weaviate、Pinecone 等同类产品最核心的差异。本文按速览、安装、上手、核心能力、生产部署、选型对比、应用场景、常见误区与面试题的结构展开,目标是让读者在 30 分钟内完成从安装到第一个检索查询。
职业价值:向量数据库是 RAG 与语义检索应用的核心基础设施,掌握 Qdrant 的建库、过滤、量化和部署方法,是从 demo 级原型走向生产级检索服务的必备选型能力。
目录
速览卡是工具类内容的固定首屏模块:30 秒判断「这工具是什么、能不能商用、适不适合我」。
为什么需要 Qdrant:从「近似搜索库」到「生产级向量数据库」
在 Qdrant 出现之前,工程团队做语义检索通常只有两类选择。一类是 FAISS、Annoy 这类近似最近邻(ANN,Approximate Nearest Neighbor,即不追求绝对精确、只求「足够接近」的近邻检索)算法库:检索快,但数据只存在于内存中,没有持久化、没有条件过滤、没有服务化 API,从「算出 Top-K」到「上线给业务调用」之间还隔着存储、并发、容灾一大堆自研工作。另一类是直接用 Elasticsearch 做语义扩展:倒排索引擅长关键词精确匹配,但在语义相似(同义改写、跨语言)上先天不足。两类方案都无法同时满足「语义检索 + 业务过滤 + 生产可用」三个条件。
Qdrant 把向量索引、payload 过滤、持久化存储、分片复制、监控指标打包成一个独立服务。payload 是附加在向量上的业务元数据(如用户 ID、类目、价格),Qdrant 允许在向量检索的同时按这些字段过滤,且过滤在索引内部完成(pre-filter),避免「先检索后过滤」导致的高分结果被丢弃。Rust 实现带来高并发与可控的内存占用;官方 SDK(Python、Go、TS/JS、Rust 等)屏蔽了 HTTP/gRPC 细节;API 在单机到集群的不同部署规模下保持一致。因此 Qdrant 常被选为 RAG 管道的默认向量存储。
与 LangChain 这类编排框架相比,Qdrant 只负责「存储 + 检索」这一层,职责单一、接口稳定;与 Milvus 相比,Qdrant 单机起步更轻、分布式组件更少;与 Pinecone 相比,它完全开源可自托管。它代表的是「检索与过滤并重」的技术路线,而不是「纯向量相似度」的简易包装。
安装与环境配置:3 步就绪
步骤一:Docker 方式(推荐)。拉取镜像并启动,容器暴露两个端口:6333 是 REST API,6334 是 gRPC。生产环境务必用 -v 挂载持久化卷,容器内数据目录为 /qdrant/storage,否则容器重建后数据丢失。启动后可访问 http://localhost:6333/dashboard 打开内置管理界面。
步骤二:二进制方式。适合没有 Docker 的生产服务器。从 GitHub Releases 下载对应平台的预编译压缩包,解压后目录内自带 config/config.yaml,直接执行 ./qdrant 即可,默认读取同目录配置。
步骤三:安装客户端并验证。Python 客户端是 qdrant-client 包;服务是否就绪用 GET /healthz 检查,返回 ok 即正常。
# 1. Docker 方式(推荐)docker run -d --name qdrant \ -p 6333:6333 -p 6334:6334 \ -v "$(pwd)/qdrant_storage:/qdrant/storage" \ qdrant/qdrant # 2. 二进制方式(Linux x86_64)curl -L https://github.com/qdrant/qdrant/releases/latest/download/qdrant-x86_64-unknown-linux-gnu.tar.gz -o qdrant.tar.gztar xzf qdrant.tar.gz && cd qdrant && ./qdrant # 3. 客户端安装与验证pip install qdrant-clientcurl http://localhost:6333/healthz
快速上手:10 分钟跑通「建库-写入-检索」
最小可用流程只有四步:连接客户端 → 创建 collection(集合,即一组向量的容器)→ upsert(写入或更新)带向量与 payload 的数据点 → search 检索。核心概念是:collection 在创建时就固定了向量维度(size)与距离度量(distance),之后不可修改,所以第一步必须先确定 embedding 模型的输出维度。
1. 创建 collection:在 Python 中指定 VectorParams(size=768, distance=Distance.COSINE),768 要与你使用的 embedding 模型输出维度一致;文本语义检索默认用 Cosine(余弦相似度)。
2. 写入数据:upsert 每个点包含 id(唯一标识)、vector(浮点数组)、payload(业务元数据字典)。
3. 执行检索:search 传入查询向量、过滤条件与返回数量,返回结果按相似度降序。
4. 进阶技巧:在 search 的 query_filter 中按 payload 字段过滤,即可实现「先过滤再检索」的复合查询。
执行后你会看到 id=2 的结果排在前面,且只返回 category="ai" 的点,说明「向量排序 + payload 过滤」在同一次查询内完成。这就是 Qdrant 和纯检索库最直观的差别。
from qdrant_client import QdrantClientfrom qdrant_client.models import Distance, VectorParams, Filter, FieldCondition, MatchValue client = QdrantClient(host="localhost", port=6333) # 1. 创建 collection(维度与 embedding 模型输出对齐)client.create_collection( collection_name="articles", vectors_config=VectorParams(size=768, distance=Distance.COSINE),) # 2. 写入数据(向量 + 业务元数据)client.upsert( collection_name="articles", points=[ {"id": 1, "vector": [0.1] * 768, "payload": {"category": "tech", "views": 1200}}, {"id": 2, "vector": [0.2] * 768, "payload": {"category": "ai", "views": 3400}}, ],) # 3. 检索:语义相似 + 按 category 过滤hits = client.search( collection_name="articles", query_vector=[0.15] * 768, query_filter=Filter(must=[FieldCondition(key="category", match=MatchValue(value="ai"))]), limit=5,)for hit in hits: print(hit.id, hit.score, hit.payload) # score 为相似度分数,越大越相似
核心能力详解:5 大支柱
支柱一:HNSW 索引与多种距离度量。Qdrant 默认使用 HNSW(分层可导航小世界图,一种通过多层图结构做近似最近邻检索的索引),在召回率与查询延迟之间取得平衡,可通过 m、ef_construct、ef 三个参数调节「内存 vs 精度」。支持四种距离度量:Cosine(余弦,文本语义检索默认)、Dot(点积,适合已归一化向量与推荐打分)、Euclid(欧氏距离)、Manhattan(曼哈顿距离,用于低维特征或特殊业务距离)。距离度量在创建 collection 时选定,之后不可更改。
支柱二:payload 过滤与复合查询。每个向量可携带任意 JSON payload,Qdrant 为 payload 字段建立独立索引,支持数值范围、字符串匹配、标签集合、嵌套对象以及地理位置过滤(圆形、矩形、多边形)。过滤与向量检索在同一次查询内执行,是 pre-filter 而非后置过滤,因此不会因过滤截断而丢失高相关结果。
支柱三:量化与内存控制。标量量化(scalar quantization)把 float32 向量压为 int8,内存降约 4 倍;二进制量化(binary quantization)压到 1 bit,向量部分内存再降一个数量级。量化会损失召回率,可配合 oversampling(过采样,即检索时多取候选再重排)补偿。这一能力让千万级向量在单节点上运行成为现实。
支柱四:多向量与混合检索。支持 named vectors(一个点存多个命名向量,例如同时存标题向量与正文向量)。自 1.12 起支持全文稀疏向量(基于 BM25 的稀疏表示),可与稠密向量做混合检索,用 RRF(倒数排名融合,把多个检索结果按排名倒数加权合并)或加权和融合,同时兼顾语义相似与精确关键词匹配——这对 RAG 中「专有名词必须精确命中」的场景尤其关键。
支柱五:分布式与运维原生能力。collection 可拆分为多个分片(shard),每个分片配置多个副本;分片分发策略支持基于 payload 字段的 hash 与自定义 key。内置快照(snapshot)备份与恢复、集合别名、Prometheus /metrics 指标端点。最核心的特性是 API 不随部署规模变化:单机进程与多节点集群使用同一套接口,迁移成本低。
生产部署与监控:从上线到运维
方式一:Docker Compose 单机部署。这是大多数团队的第一站,但生产环境必须补三件事:挂载持久化卷(容器内 /qdrant/storage)、配置 restart 策略、限制容器资源。一个最小可用的 compose 配置如下,./qdrant_storage 会落在宿主机上,容器重建不丢数据。
方式二:Kubernetes / Helm 与 Qdrant Cloud。需要水平扩展时,官方 Helm chart 支持分片副本、持久卷声明与水平扩缩容;Qdrant Cloud 则提供全托管与混合云部署,把升级、备份、监控全部外包。选型依据很简单:团队有 7×24 运维能力的选自托管,没有则优先托管服务;日向量查询量在千万级以下,单机 + 量化通常已经够用。
可观测性。Qdrant 在 6333 端口暴露 /metrics,输出 Prometheus 格式指标(向量点数、分片状态、请求延迟直方图),接入 Prometheus 后可用 Grafana 展示;健康检查使用 GET /healthz 与 GET /livez;日志默认 JSON 格式便于采集。备份策略建议用快照 API 定期导出到对象存储,而不是直接拷贝数据目录。
<p class="para-label">避坑清单:</p>
<ul class="dash-list"><li>生产环境不挂载持久化卷:Docker 容器默认数据写在容器内层,重启或重建即全部丢失;务必挂载 /qdrant/storage,并对卷做独立备份。</li><li>向量维度与距离度量创建后不可修改:建 collection 时若 size 设错,只能删除重建并重灌数据;先确认 embedding 模型输出维度,再决定 384/768/1536 等取值。</li><li>升级版本前先做快照与恢复演练:Qdrant 快照在同版本恢复最可靠,跨大版本恢复前必须在测试环境验证,降级方向尤其危险。</li></ul>
services: qdrant: image: qdrant/qdrant:latest ports: - "6333:6333" - "6334:6334" volumes: - ./qdrant_storage:/qdrant/storage restart: unless-stopped
| 维度 | Qdrant | Milvus | Weaviate | Pinecone |
|---|---|---|---|---|
| 定位 | Rust 开源向量数据库,检索与过滤并重 | Go/C++ 开源分布式向量数据库 | Go 开源向量数据库,内建知识图谱 | 全托管向量数据库 SaaS |
| 部署形态 | 单机二进制 / Docker / K8s / 云 | Milvus Lite 单机 / Docker / 分布式 | Docker / K8s / 嵌入式模块 | 纯托管,无自托管选项 |
| 过滤能力 | 强:嵌套过滤、全文索引、地理过滤、复合条件 | 中:标量字段过滤 | 中:class 属性过滤 + GraphQL 查询 | 中:metadata 过滤 |
| 存储压缩 | 标量/二进制量化 + oversampling | 量化 + MMap,组件多 | PQ 压缩 | 自动索引,细节不可控 |
| 混合检索 | 稀疏向量 + 加权/RRF 融合 | 稀疏稠密混合(v2.4+) | 多向量 late fusion | 部分支持 |
| 学习曲线 | 低:一套 API 从单机到集群 | 中:coordinator/query/index 组件多 | 中:需熟悉 GraphQL 语法 | 低:API 简单 |
| License | Apache 2.0 | Apache 2.0 | BSD-3-Clause | 商业 |
| 适合谁 | RAG / 搜索 / 推荐团队 | 超大规模分布式、Deep K8s 团队 | 语义搜索 + 知识图谱场景 | 快速原型、无运维团队 |
选型建议:单机起步、强调 payload 过滤与混合检索的 RAG 项目,优先选 Qdrant;已有成熟 K8s 且向量规模在十亿级以上、需要弹性扩展的团队,Milvus 更合适;需要内建知识图谱和 GraphQL 语义查询的选 Weaviate;不想承担任何运维成本、追求最快上线的选 Pinecone。建议在选定前用自身数据做过滤场景压测,三个开源工具均可本地部署验证。
版本迭代
Qdrant 于 2021 年开源,2022 年在 0.x 阶段快速迭代,2023 年 7 月发布 1.0 稳定版,此后以约每月一版的节奏演进。主线清晰:从「可用的向量检索服务」→「过滤与多向量能力」→「量化与内存优化」→「稀疏向量与混合检索」,每次大版本都直接扩大可用场景边界。(截至训练数据,可能已有更新版本)
| 版本 | 时间 | 变化 | 提升 |
|---|---|---|---|
| v1.0.0 | 2023-07 | 首个正式稳定版 | REST/gRPC API 转正,支持事务与快照备份,进入生产可用阶段 |
| v1.5.0 | 2023-12 | 过滤与查询能力增强 | payload 过滤能力增强,HNSW 检索性能与稳定性优化 |
| v1.7.0 | 2024-02 | 多向量支持 | 每个点可存多个命名向量,支持按向量名查询与过滤 |
| v1.10.0 | 2024-06 | 二进制量化稳定 | 向量内存占用压缩约一个数量级,oversampling 补偿召回率 |
| v1.12.0 | 2024-09 | 全文稀疏向量 | 内置 BM25 全文检索,与稠密向量融合实现混合检索 |
| v1.15.0 | 2025-02 | Agent 与混合检索增强 | 面向 Agent 场景的检索能力强化,部署与交付体验优化 |
本工具未发布可复现的权威第三方榜单成绩,评测数据对比表省略;公开基准多见于官方博客的内部对比,结论是过滤检索场景下 Qdrant 高并发表现突出,选型时应以自建场景压测为准。实际工程影响最大的两次迭代是 v1.10 的二进制量化(把千万级向量的内存成本降到一个数量级以下)和 v1.12 的全文稀疏向量(让关键词精确匹配与语义检索共用一套 API)。
AI 应用场景
场景一:企业级 RAG 知识库
阶段:RAG 管道构建 / 文档智能
解决的问题:RAG 要求「先按语义召回相关片段,再按租户、时间、权限过滤」,传统「全部召回后应用层过滤」的方案会丢弃被过滤掉的高分结果。Qdrant 把过滤下推到索引内完成(pre-filter),一次查询同时满足语义与权限要求;配合 payload 中的部门、可见性等级实现多租户隔离,配合稀疏向量对产品型号等专有名词做精确匹配兜底。
具体案例:某企业内部知识库将约 200 万条文档分块 embedding(768 维)写入 Qdrant,每条附带部门与更新时间的 payload;检索时按部门过滤 + 语义排序,常规生产配置下单查询 P95 延迟在数十毫秒内,整体检索耗时相比旧方案下降一个数量级。
场景二:推荐系统语义召回
阶段:向量召回 / 推荐系统
解决的问题:推荐粗排前需要从千万级物品中召回候选,纯 embedding 检索无法表达「只能推某店铺、某价格带、某地域」等业务约束。Qdrant 支持在召回阶段用 Dot 距离(适合打分排序)加 payload 过滤(店铺、价格区间、类目、上架状态)直接产出候选集,在召回阶段就剔除大部分不满足条件的物品。
具体案例:电商场景将物品 embedding(128~512 维)与店铺 ID、价格字段写入同一 collection;召回时附带店铺与价格上限过滤,单次召回延迟毫秒级,相比「全量检索后再过滤」的方案,召回候选更精准,粗排阶段的无效计算显著减少。
场景三:实时风控与异常检测
阶段:实时推理 / 流式数据处理
解决的问题:支付与登录风控需要把「当前行为」与「历史行为分布」做快速相似比较,异常点即与最近邻距离超过阈值的点。Qdrant 支持高吞吐写入与增量 upsert,行为向量可流式入库,配合时间范围过滤实现「只比较近 24 小时行为」的滑动窗口查询。
具体案例:风控团队将设备指纹与会话行为聚合为向量实时写入,查询时按时间戳过滤,与历史正常行为向量比较距离;相比每次全量计算距离的批处理方案,响应从分钟级降到百毫秒级,可支撑在线决策。
常见误区
误区直接把文本或图片传给 Qdrant,以为它会自己完成向量化并存储。
正解Qdrant 是向量存储与检索层,不负责生成 embedding。向量必须由外部模型(如 OpenAI、BGE、Cohere)生成后,通过 upsert 写入。官方提供 FastEmbed 这类客户端库来简化本地 embedding 生成,但必须在客户端显式引入;服务端默认不做任何文本向量化。
为何常见:很多向量数据库厂商宣传「端到端」,且 RAG 教程常把 embedding 模型与向量数据库混在一起讲,导致职责边界被忽略。
误区把 Qdrant 等同于 FAISS 这类纯内存算法库,认为数据重启即丢、无法水平扩展。
正解Qdrant 从设计上就是持久化数据库,向量与 payload 落在磁盘上;分布式模式支持 collection 分片(shard)与副本(replica),节点故障时副本继续提供读服务,写入通过一致性配置保证。单机进程只是最小部署单元,不是能力上限。
为何常见:大多数教程用 Docker 单容器演示,短平快的上手体验让人忽略了它完整的分布式能力。
误区embedding 模型输出 1536 维就用 1536 维,认为维度越高检索越准。
正解维度增加会带来内存与检索耗时线性增长,而召回率提升有限。正确做法是让 collection 的 size 与所选 embedding 模型的输出维度严格一致(常见 384、768、1536),并通过量化控制成本,而不是盲目追求高维。
为何常见:主流 embedding 模型普遍输出高维向量,用户误以为「模型输出就是最优配置」,忽略了维度与硬件成本的权衡。
误区payload 里存了文本字段,就以为 Qdrant 能像 Elasticsearch 一样做关键词全文检索。
正解payload 默认不建立全文索引,普通字符串匹配是精确匹配而非分词检索。需要关键词搜索时,要么在建索引时为文本字段开启 full-text index,要么使用 1.12+ 的全文稀疏向量能力;纯粹的倒排索引搜索并非 Qdrant 的设计目标。
为何常见:看到 payload 能存储任意 JSON,默认以为存储即检索,混淆了「结构化字段过滤」与「全文检索」两种能力。
误区向量数据库就是「升级版搜索引擎」,任一场景下两者随便换。
正解两者定位不同:Elasticsearch 以倒排索引为主,擅长关键词精确匹配与聚合分析;Qdrant 以向量相似度为主,擅长语义匹配与向量+元数据复合过滤。混合需求(既要语义又要精确关键词)的正确做法是使用 Qdrant 的混合检索(稠密 + 稀疏),而不是简单二选一。
为何常见:两者都叫「索引」「查询」,概念重叠多,不深入理解倒排与向量两种数据结构差异时很容易混淆。
面试题
Q1. Qdrant 服务端核心引擎主要使用哪门语言编写?
- A.Go 语言
- B.Rust 语言← 正确答案
- C.Java 语言
- D.C++ 语言
答案:B。Qdrant 服务端完全由 Rust 编写,Rust 的内存安全与高并发性能是其高吞吐检索的基石。Go 是 Weaviate 的实现语言,C++ 是 Milvus 存储层选型,Java 不在 Qdrant 技术栈中,Python 仅用于官方客户端。
Q2. Qdrant 默认使用的向量索引算法是?
- A.HNSW 索引← 正确答案
- B.IVF-PQ 索引
- C.FLAT 索引
- D.MRPT 索引
答案:A。Qdrant 默认使用 HNSW(分层可导航小世界图)索引,在召回率与查询延迟之间取得平衡。IVF-PQ 是 Milvus 等系统常见的索引类型,FLAT 是暴力扫描,MRPT 是 FAISS 的索引,均不是 Qdrant 默认选择。
Q3. 使用 Docker 启动 Qdrant 后,REST API 默认监听端口是?
- A.6333 端口← 正确答案
- B.6334 端口
- C.8080 端口
- D.9200 端口
答案:A。6333 是 REST API 端口,6334 是 gRPC 端口,两者在 Docker 启动命令中都要映射。8080 是常见 Web 服务默认端口,9200 是 Elasticsearch 的默认端口,与 Qdrant 无关。
Q4. 创建 collection 时,向量的维度(size)应如何确定?
- A.与 embedding 模型输出维度一致← 正确答案
- B.维度越大检索效果一定越好
- C.与文档数量保持相同数值
- D.任意设置一个固定常数即可
答案:A。向量维度必须与 embedding 模型输出维度严格一致(如 384、768、1536),否则查询时维度不匹配会报错。维度并非越大越好,内存与检索成本随维度线性增长,collection 创建后维度不可修改,选错只能重建。
Q5. 下列哪些距离度量属于 Qdrant 官方支持?
- A.Cosine 距离← 正确答案
- B.Dot 距离← 正确答案
- C.KL 散度值
- D.Euclid 距离← 正确答案
答案:ABD。Qdrant 的 Distance 枚举包含 Cosine、Dot、Euclid、Manhattan 四种度量。KL 散度是概率分布之间的距离度量,不在 Qdrant 支持范围内。选择哪度量取决于业务:文本语义默认 Cosine,已归一化向量的推荐打分常用 Dot。
Q6. 二进制量化(Binary Quantization)的主要作用是?
- A.压缩向量内存占用← 正确答案
- B.提升 embedding 模型精度
- C.替代 HNSW 索引
- D.扩大向量搜索范围
答案:A。二进制量化把每个向量维度压缩为 1 bit,向量内存占用可降约一个数量级,是 Qdrant 控制大规模内存成本的核心手段。它不改变 embedding 语义,也不替代 HNSW 索引,量化造成的召回损失需用 oversampling 补偿。
Q7. 关于 Qdrant 分布式部署,下列说法正确的是?
- A.collection 可分为多个分片← 正确答案
- B.分片可配置副本数量← 正确答案
- C.分布式模式必须依赖 K8s
- D.副本可提高读取可用性← 正确答案
答案:ABD。Qdrant 分布式模式下 collection 可拆分为多个分片,每个分片可设置副本数;副本在节点故障时继续提供读取,提升可用性。分布式模式不强制依赖 K8s,Docker 集群亦可运行,K8s 只是官方支持的一种部署方式。
Q8. 为 collection 创建快照的 REST API 是?
- A.POST /collections/{name}/snapshots← 正确答案
- B.GET /collections/{name}/snapshots
- C.POST /snapshots/{name}/create
- D.PUT /collections/{name}/backups
答案:A。Qdrant 的快照创建 API 是 POST /collections/{collection_name}/snapshots,返回任务 ID;GET 同路径用于列出已有快照,PUT /backups 与 /snapshots/{name}/create 都不是官方定义。快照下载则使用 /snapshots/{snapshot_name}。
Q9. 下列哪些客户端由 Qdrant 官方提供?
- A.Python 官方 SDK← 正确答案
- B.Go 官方 SDK← 正确答案
- C.TS/JS 官方 SDK← 正确答案
- D.Ruby 社区 SDK
答案:ABC。Qdrant 官方维护 Python、Go、TypeScript/JavaScript、Rust 等客户端 SDK,覆盖主流服务端语言。Ruby 客户端不在官方支持列表中,属于社区实现,官方文档也未将其列入,生产选型时应优先使用官方 SDK。
Q10. 关于 Qdrant 快照恢复,下列说法错误的是?
- A.快照可用于数据迁移
- B.快照保存在 storage 目录
- C.快照只能在原节点恢复← 正确答案
- D.快照可跨集群恢复数据
答案:C。Qdrant 快照可下载、可迁移,也可恢复到其他节点甚至其他集群,并非「只能在原节点恢复」;A、B、D 描述均正确。快照是官方推荐的备份与迁移手段,生产环境应定期导出到对象存储,并在恢复前做演练。