向量检索为什么这么慢?Qdrant 向量数据库从跑通到生产(完整速查表)
2026/9/2 10:35:31 网站建设 项目流程

向量检索为什么这么慢?Qdrant 向量数据库从跑通到生产(完整速查表)

【免费下载链接】qdrantQdrant - High-performance, massive-scale Vector Database and Vector Search Engine for the next generation of AI. Also available in the cloud https://cloud.qdrant.io/项目地址: https://gitcode.com/GitHub_Trending/qd/qdrant

你的语义搜索 Demo 在 1 万条数据上跑得飞快,量级一到千万,延迟从 50ms 跳到 5s,内存也跟着爆掉。问题往往不在模型,在向量检索层。Qdrant 向量数据库是用 Rust 写的向量搜索引擎兼向量数据库,一个服务里把向量和元数据的存储、近似最近邻搜索、复杂过滤全部接住,高压负载下依然稳定。

这篇文章只讲一条线:先跑通,再谈优化,最后落到生产。不解释你早就知道的"什么是向量",只讲怎么把检索延迟和内存这两件事真正压下来。

一、一张图看懂:向量在 Qdrant 里是怎么存、怎么查的

先给你一个心智模型:你往 Qdrant 里写的每个点(Point)= 向量 + 任意 JSON 载荷(payload);点装在**集合(Collection)里;集合内部按段(Segment)**切分,每个段自带向量索引(HNSW)和载荷索引(payload index);查询进来时,各段并行搜索再归并出 Top-N。

这里要记住一个原则:过滤是跟着索引走的,不是搜完再筛。Qdrant 会按字段类型自动建载荷索引(关键词、整数、浮点、地理、全文),查询规划器根据条件命中量决定走 HNSW 还是直接暴力扫(full_scan_threshold_kb控制这个切换)。所以"带过滤的向量搜索慢"这个经典问题,在 Qdrant 里靠的是规划器选路,而不是你写代码去兜底。

Qdrant 里向量有三种形态,选错形态后面全白忙:

形态数据长什么样典型场景
稠密 Dense固定维度浮点向量语义相似度、RAG
稀疏 Sparse稀疏向量(BM25/TF-IDF)关键词与全文匹配
多向量 Multi一个对象挂多个向量(如 ColBERT 类晚交互模型)高精度细粒度匹配

二、5 分钟跑通:三条命令拿到第一次搜索结果

先别碰任何配置。一条命令起服务:

docker run -p 6333:6333 -p 6334:6334 -v $(pwd)/qdrant_data:/qdrant/storage qdrant/qdrant

注意:这是无认证、监听所有网卡的实例,只配本地玩。生产怎么收口,第六节讲。

然后 Python 客户端把"建集合 → 写入 → 查询"一次做完:

from qdrant_client import QdrantClient, models client = QdrantClient(url="http://localhost:6333") client.create_collection( "docs", vectors_config=models.VectorParams(size=8, distance=models.Distance.COSINE), ) client.upsert("docs", points=[ models.PointStruct(id=1, vector=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8], payload={"lang": "zh", "score": 4.5}), models.PointStruct(id=2, vector=[0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2], payload={"lang": "en", "score": 3.1}), ]) hits = client.query_points("docs", query=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8], limit=2) print(hits)

用 curl 验证服务和集合状态:

curl http://localhost:6333/health curl http://localhost:6333/collections/docs

跑通之后注意一个细节:刚写入的点在"原始段"里做暴力搜索,等段内向量累计超过indexing_threshold_kb(默认 10000KB,约等于 256 维向量 4 万条),后台优化器才开始建 HNSW 索引。小数据量下暴力扫反而更快,这是设计而不是缺陷。

三、三个核心能力:过滤、混合、量化

3.1 过滤:载荷不是装饰

RAG 场景十有八九要"先按租户/时间/类别圈范围,再搜"。Qdrant 的过滤是must/should/must_not三层布尔组合:

from qdrant_client.http import models res = client.query_points( "docs", query=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8], query_filter=models.Filter( must=[ models.FieldCondition(key="lang", match=models.MatchValue(value="zh")), models.FieldCondition(key="score", range=models.Range(gte=4.0)), ], must_not=[ models.FieldCondition(key="status", match=models.MatchValue(value="archived")), ], ), limit=10, )

支持的字段类型覆盖关键词匹配、全文、数值区间、地理围栏、嵌套路径。前面说过,规划器会看这些条件的选择性自动选索引路径——你不需要手写"该不该建索引"。

3.2 混合搜索:一条查询同时打稠密和稀疏

纯语义搜索抓不住精确词,纯关键词抓不住语义。Qdrant 让你在同一条查询里放稠密向量 + 稀疏向量,结果按可配置策略融合:RRF(Reciprocal Rank Fusion)或 DBSF(基于分数的融合)。多向量场景(ColBERT 类)也走同一个查询接口。

3.3 量化:拿精度换内存

内存装不下 HNSW 索引,是第一常见事故。内置量化的内存节省最高到 97%,建集合时直接挂上:

client.create_collection( "docs_q", vectors_config=models.VectorParams(size=384, distance=models.Distance.COSINE), quantization_config=models.ScalarQuantization( scalar=models.ScalarQuantizationConfig( type=models.ScalarType.INT8, quantile=0.99, always_ram=True ) ), )

选型口径:Scalar(4 倍压缩)精度损失小,先试它;Product(8~64 倍)上大规模;Binary(32 倍)要极速检索且能容忍损失。量化后建议开启 rescore,用原始向量对 Top 结果重打分,把精度找补回来。

四、数据路径:段、WAL 和后台优化器

把第二章跑通的东西拆开看,就明白"写入为什么快、搜索为什么稳"了。

Qdrant 集合内部结构(源码仓库内文档图):

要点:一个 Collection 不是一张大表,而是多个 Segment 的集合。原始段只有向量存储和载荷;索引建好后变成完整段(向量索引 + 载荷索引 + ID 映射 + 版本存储);段之间靠代理段(proxy)做无感切换。

更新请求的流转顺序:

还是那个原则:写入先落 WAL,段更新异步进行,优化器在后台做苦力。WAL 保证掉电不丢已确认的写入;优化器负责合并段、清理删除的向量、构建索引——第二章提到的"超阈值才建索引"就是它干的。这也解释了运维时你该盯什么:deleted_threshold(删除比例超过 0.2 触发整理)和vacuum_min_vector_number(低于这个数量的段不参与合并)调不好,要么磁盘膨胀,要么段数失控。

五、生产部署:单节点与集群两种形态

5.1 单节点最小生产配置

storage: storage_path: /data/qdrant/storage snapshots_path: /data/qdrant/snapshots on_disk_payload: true # 载荷放磁盘,省内存 performance: max_search_threads: 0 # 0 = 自动 optimizers: deleted_threshold: 0.2 vacuum_min_vector_number: 10000 indexing_threshold_kb: 10000 service: http_port: 6333 grpc_port: 6334 # gRPC 面向生产级搜索 max_request_size_mb: 64 api_key: "change-me-strong-key"

仓库里带完整注释的默认配置可以直接当字典查:config/config.yaml。

5.2 集群形态

打开cluster.enabled: true,配好p2p.port: 6335和共识参数(tick_period_ms: 100官方明确建议别动)。两个参数控制数据冗余,建集合时可单独指定:replication_factor(每个分片几个副本)和write_consistency_factor(几个副本确认算写成功)。

三个生产要点:

  • 零停机扩缩:加节点、增删分片(resharding)都不需要停服务,这也是 2025 路线图里"持续改善可扩展性"的核心方向,规划见 docs/roadmap/README.md。
  • 只读/备份节点storage.node_type设为Listener的节点只接收更新、不回答查询,适合做专用备份节点,给主集群省搜索资源。
  • gRPC 优先:REST 好调试,gRPC(6334)是生产搜索的高吞吐通道,两者都开,各取所需。

5.3 生产配置速查

配置作用什么时候改
storage.on_disk_payload载荷放磁盘内存紧张就开,响应时间换内存
hnsw_index.m/ef_construct索引边数 / 构建邻域精度优先往上调(16→32),内存优先往下调
optimizers.indexing_threshold_kb段建索引阈值小数据暴力扫更快,别强建索引
optimizers.max_segment_size_kb段上限更看重建索引速度就调小
cluster.consensus.tick_period_ms共识心跳不建议改,动了会放大网络开销

六、上线前清单:安全与监控

安全不是可选项,Qdrant 的默认配置是无认证裸奔的。上线前逐项过:

  • API Key + TLS 必须成对开service.api_key只设 key 不开 TLS,密钥等于明文传输,官方注释里直接写了这是不安全操作。同时开enable_tls: true并配好tls.cert/tls.key/ca_cert
  • 读写分权read_only_api_key给监控和 BI 用,出问题也查得到数据。
  • 集群内部通信加密cluster.p2p.enable_tls: trueca_cert是必需的。
  • 细粒度授权:开jwt_rbac后可按规则签发细粒度 JWT,替代一把梭的 API key。
  • 配额兜底quotas段里设max_resident_memory_percentmax_disk_usage_percent,防止某个写入大户把节点打满,触发后节点会拒绝消耗资源的写入。
  • 审计日志:开audit.enabled,每次过权限检查的 API 请求都落 JSON 审计。

监控三件套端点:/health(存活)、/metrics(Prometheus 格式)、/cluster(集群状态)。盯住三类指标:搜索/更新耗时分布、集合数量与向量数、磁盘使用量。带过滤的慢查询先看 P99 分位,再看/collections/{name}里各段的索引状态,定位是索引没建好还是段太碎。浏览器直接访问http://<host>:6333/dashboard有 Web UI,可以交互式查集合、发请求。

七、故障速查与升级路径

症状最可能的原因第一步处理
搜索慢、P99 漂移段未建索引 / HNSW ef 偏小 / 无量化查集合状态,调hnsw_ef或开量化
磁盘持续增长段数失控、优化器不激进检查deleted_thresholdvacuum_min_vector_number
重启后内存 OOM常驻数据太大,启动加载即爆storage.low_memory_mode: no_resident降级加载,再逐步恢复
集群节点失联6335 端口不通 / 网络分区验证 p2p 网络连通性,查/cluster
快照恢复失败跨版本跳跃 / 文件不完整校验快照完整性,按连续版本逐个升级

升级路径记住三句话:

  1. 存储格式在相邻版本间兼容,数据会自动迁移,滚动更新即可,不需要停机导数。
  2. 路线图承诺至少回退一个 minor 版本的向后兼容,客户端与服务端版本不匹配时会主动提示。
  3. 动手前先打快照备份:POST /snapshots创建,PUT /snapshots/recover恢复;跨实例迁移就是"打快照 → 下载 → 目标实例恢复"三步。

八、行动清单

✅ 本地 docker 跑起 Qdrant,完成第一次带过滤的向量搜索 ✅ 建一个开启 Scalar 量化的集合,对比量化前后的内存占用 ✅ 照第五节写出你的生产 config,api_key与 TLS 同时开启 ✅ 把/metrics接进 Prometheus,给搜索耗时和磁盘用量设告警 ✅ 打一次完整快照并做恢复演练,验证备份真实可用 ✅ 若上集群:演练节点掉线、resharding、滚动升级三个动作

先跑通,再谈优化。把清单里的每一项做完,你的向量检索层才算真正进入生产状态。

【免费下载链接】qdrantQdrant - High-performance, massive-scale Vector Database and Vector Search Engine for the next generation of AI. Also available in the cloud https://cloud.qdrant.io/项目地址: https://gitcode.com/GitHub_Trending/qd/qdrant

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询