基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
  • 知识卡片碎片时间过考点
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
    • AI 热点每日 AI 资讯与动向
AI 工作台
简历
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
技术实践2026-11-04 05:10

Dify 高并发检索:两种向量库压测

dev.to · AI#向量数据库#Dify#性能测试
Editor brief · 编辑速览

作者在5万条1536维向量、500并发会话环境下比较 pgvector 与 Qdrant,报告后者 p99 延迟为290毫秒,前者为680毫秒,但后者内存占用更高。测试列出了硬件、版本和索引参数,关于写入锁导致延迟差异的归因仍需验证。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

500 个并发 Agent 会话同时检索知识库,换成专用向量数据库能省下多少等待?作者用 Dify、pgvector 和 Qdrant 做了一轮压力测试:Qdrant 的尾延迟更低,代价是更多内存;pgvector 经过分区后,也有改善空间。

这组结果可以帮团队设计压测,但还不足以直接决定选型。原文把测试观察、原因推测和产品推荐混在了一起,部分 SQL 与向量归一化解释还有明显疑点。真正值得带走的,是怎么拆开延迟、召回率和成本来看。

Qdrant 更快,但这轮测试证明了多少

作者的环境是 Docker Compose 部署的 Dify v0.6.13,运行在 8 核 AMD EPYC、32GB RAM、NVMe SSD 上。数据集包含 50k 篇文档,使用 1536 维 OpenAI embeddings;查询结合向量检索、关键词检索,以及 user_id、时间范围过滤。

两套后端分别是:

  • PostgreSQL 15 + pgvector 0.5.1,HNSW 参数为 m=16、ef_construction=64。
  • Qdrant 1.7.4,HNSW 参数为 m=16、ef_construct=100。

负载由 HTTP 工具 wrk 和 Python SDK 测试工具 pytest-asyncio 产生,持续 300s,开启 500 个并行 Agent 会话。

这里先要分清:500 个并发会话,不等于每秒完成 500 次请求。 标题写了 500 RPS,正文却没有实际吞吐、请求间隔和错误率,无法确认这个吞吐是否达到。

作者报告,在并发写入时,Qdrant 的 p99 延迟优势达到 2.3 倍,pgvector 的 p99 为 680ms。p99 可以理解为:约 99% 的请求耗时不超过这个值,它比平均延迟更能暴露少数用户的长时间等待。

代价是 Qdrant 多消耗 62% RAM。作者归因于内存中的 payload 缓存,也就是随向量保存、用于过滤的附加字段缓存,但没有给出两边实际内存占用。

召回率方面,pgvector 从冷启动时的 0.94 降至持续负载下的 0.91,Qdrant 保持 0.94。原文未交代标准答案、查询集和测量口径,这些数值只能作为该实验的报告结果。

两组 HNSW 构建参数也不一致。没有搜索参数、写入比例和重复实验,暂时无法把全部差距归到数据库架构上。

分区值得试,原文 SQL 却不能直接上线

作者把 pgvector 的延迟归因于 HNSW 在 INSERT 时获取排他锁,导致查询阻塞;把 Qdrant 的优势归因于 WAL 写入管线将索引构建与搜索分离。

这是需要验证的原因解释。原文没有锁等待记录、执行计划或性能剖析,也没有证明召回率下降确实来自其猜测的「索引维护不完整」。

他们团队随后尝试冷热分区,报告 p99 从 680ms 降到 420ms。思路有参考价值:把持续写入集中到热分区,让历史数据的读取少受写入影响。不过,原文说这能「消除锁竞争」,证据还不够。

更直接的问题在 SQL:

其一,表按 created_at 分区,却只声明 id UUID PRIMARY KEY。PostgreSQL 分区表的主键约束需要包含分区键,这段定义存在执行障碍。

其二,注释说热分区覆盖最近 7 天,实际范围却是 '2024-01-01' 到 '2024-12-31',不是滚动窗口,也没有展示后续分区维护。

其三,查询只访问 knowledge_segments_hot,没有历史分区,无法展示「旧数据查询免受热写入影响」的完整路径。

最后,排序里的 ts_rank(...) 是占位写法。它还把向量相似度与关键词分数按 0.7、0.3 相加,未交代分数量纲如何对齐,也不能假定这种混合排序会直接利用 HNSW 完成取前 10 条。

因此,420ms 是作者报告的优化结果,不能当作复制这段 SQL 就能获得的收益。

混合检索的思路可用,归一化结论要重查

原文另一项实践是倒数排名融合(RRF):分别拿到向量检索和 BM25 关键词检索结果,再按名次合并。

它解决的是两个分数不好直接比较的问题。RRF 不直接相加原始分数,而是给每条结果累加 1 / (k_constant + rank);同一文档在两路都排得靠前,最终分数就更高。

示例中,hybrid_search_rrf 默认 top_k=10、k_constant=60,两路各取 top_k * 2 条,通过 asyncio.gather 并行请求,再按 segment_id 去重和排序。httpx.AsyncClient(timeout=30.0) 设置了请求超时。

作者使用 Dify Knowledge API 的 /v1/datasets/{knowledge_id}/retrieve,传入 retrieval_mode="vector" 或 "keyword",并提醒 "Vector" 会返回缺少有效说明的 400 错误。这是作者报告的踩坑经验;接口字段、返回结构和检索模式仍应对照实际部署版本的 OpenAPI,示例本身不能证明版本兼容性。

归一化部分更需要谨慎。作者建议入库前把向量缩放到单位长度,代码如下:

import numpy as np

def normalize_embedding(embedding: List[float]) -> List[float]:
    vec = np.array(embedding)
    norm = np.linalg.norm(vec)
    if norm == 0:
        return embedding  # Avoid division by zero
    return (vec / norm).tolist()

这里要看的是最后一行:它只改变向量长度,不改变方向;代码单独运行还需要导入 List。

真正的余弦相似度,不会因为非零向量做了这种归一化就改变排名。 原文前面使用 vector_cosine_ops 和 <=>,因此「未归一化导致余弦排序错误」这个解释并不充分。若实际使用内积、不同距离配置或其他处理流程,需要另行说明。

作者报告归一化后,同一 pgvector 索引的 recall@10 从 0.87 升到 0.94,但没有提供足够信息解释原因。其调用示例还用了 openai.Embedding.create 和 text-embedding-ada-002,不能直接视为适配当前 SDK 的入库方案。

我的判断

我认可作者把读写混合负载、p99 和内存成本放在一起比较。Agent 的检索链路确实不能只看一次查询有多快,写入和过滤条件也应进入测试。

但这篇更像实验记录,尚不是可复现的选型报告。延迟、内存和召回率属于作者报告的测量;锁机制解释、归一化归因,以及分区「消除」竞争,则需要更多证据。

作者建议在持续写入超过 100 docs/sec、p99 SLA 低于 300ms、内存可承受 1.5x+ 开销时考虑 Qdrant;数据少于 100k 向量、夜间 ETL 批量写入,或需要向量与关系数据共享 ACID 事务时保留 pgvector。这些是经验边界,没有覆盖这些阈值的对照实验,不能当作通用分界线。

混合部署也有额外成本:Qdrant 服务实时查询,pgvector 保存审计主记录,需要处理同步、删除和一致性。原文称在 docker-compose.yaml 中为不同 Knowledge bases 配置 provider 即可,但没有展示配置和同步实现。

文末还插入 B-Lost 中继案例:通过 https://b-lost.com/v1 调用 gpt-4,声称比直连 OpenAI 的首 Token 时间(TTFT)低 35ms、没有 token 截断,并归因于 CDN 缓存模型元数据与 tokenizer 配置。没有网络路径和对照数据,这段不足以支撑网关选型,也不能用于解释向量检索结果。

能拿来做什么

  • 给 Node 或全栈知识库服务压测时,同时记录实际 RPS、并发数、错误率、p99 和写入速率,并保留租户过滤与时间过滤,避免只测无过滤的纯向量查询。
  • 现有 pgvector 服务出现尾延迟时,先查锁等待、执行计划和索引使用情况,再试冷热分区;不要直接复制原文 SQL,也不要仅凭 50k 数据规模决定迁移。
  • 实现混合检索时,可以沿用 RRF 按排名融合的思路,同时验证 API 字段、超时、响应结构和单路失败处理,再比较召回质量。
  • 调查召回率下降时,先固定查询集与标准答案,核对 embedding 模型、距离算子和过滤条件,再决定是否调整归一化流程。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
Agent 接入现有 API 的权限与架构选择
下一篇
苹果向开发者开放 Siri 多步骤任务接入

资讯速览

dev.to · AI · 2026-11-04 05:10

AI 评分 8.0 / 10

相关标签

#向量数据库#Dify#性能测试

继续阅读

  • Agent 工具设计:让代码承接复杂流程
  • Agent 接入现有 API 的权限与架构选择
  • 苹果向开发者开放 Siri 多步骤任务接入
  • Soniox 新版语音识别引入 Agent 文本上下文
  • Siri 开放第三方应用操作与任务组合