在生产环境中运行搜索需要什么?
一家中型电商公司推出了一个向量搜索试点项目,以改善产品发现。在测试期间,一切运行顺利。但在生产环境中,他们的查询开始间歇性地失败:内存错误、磁盘 I/O 飙升和搜索延迟意外出现。
结果发现,团队没有调整默认配置设置,也没有为预写日志保留专用路径。他们的向量索引太大,无法完全容纳在 RAM 中,频繁溢出到磁盘,导致速度变慢。
像这些问题强调了默认配置在生产负载下可能会出现灾难性的失败。
在生产环境中运行向量搜索是为了确保可靠性、性能和弹性——无论您的托管环境如何。无论您是在裸机、虚拟机还是容器编排环境中,管理内存限制、配置数据分布、选择索引和备份都至关重要。
本指南解决生产环境中常见的问题
无论您是计划首次部署还是希望改进现有系统,本教程都将帮助您构建弹性且高性能的向量搜索基础设施。
本文将帮助您在生产环境中成功部署和维护向量搜索系统。
借鉴我们用户的真实世界经验,您将发现实用技巧,以避免许多生产部署中常见的陷阱。
目录
1. 如何获得最佳搜索性能?
“在我们添加更多向量后,搜索变得超级慢。” |
❓ 用例:一家客户支持初创公司看到了间歇性的延迟峰值。他们的索引超出了可用内存,因此频繁地从磁盘获取数据。升级 RAM 有所帮助,而对所有数据进行量化成为了真正的关键。用户所做的只是管理他们的内存负载,减少内存中的向量,并将其余数据卸载到磁盘。
如果这正在发生,那么您的索引设置很可能没有优化,系统会更频繁地访问磁盘,从而增加延迟。
确保您的热数据集能完全放入 RAM 中,以实现低延迟查询。
如果不能,那么您将不得不将数据“卸载到磁盘 (on_disk)”。如果启用此参数,Qdrant 会将您最常访问的向量加载到 RAM 中进行缓存,其余数据则内存映射到磁盘。
这确保了查询期间的最小磁盘访问,显著降低了延迟并提高了整体性能。通过监控查询模式和使用指标,您可以确定哪些数据子集应该享有专用的内存存储空间,而仅将磁盘访问保留给不常查询的冷数据向量。
阅读更多: 存储文档 |
索引重要的元数据以避免昂贵的查询
✅ 您应该始终为用于过滤或排序的所有字段创建载荷索引(payload index)。
许多用户配置了复杂的过滤器,但可能没有意识到需要创建相应的载荷索引。
结果是,每个查询都会扫描数千个向量及其原始载荷,然后丢弃大部分不符合过滤条件的向量。这会导致 CPU 使用率飙升和响应时间过长,尤其是在较高流量负载下。
在检索了数千个向量之后再进行过滤会非常耗费资源。如果您不在查询中进行过滤,Qdrant 将评估比您需要的更多的向量。这将使整个系统变慢并消耗更多资源。正因为如此,我们开发了自己的 HNSW 版本——可过滤向量索引(The Filterable Vector Index)。
与其他一些引擎不同,Qdrant 允许您为您的用例选择要索引哪些字段的最佳方案,而不是默认对所有字段创建索引。
注意:不要忘记使用正确的载荷索引类型。如果存在数值,则必须使用数值索引。如果您将数字表示为字符串(如“123”),则数值索引将不起作用。
阅读更多: 过滤文档 |
别忘了调整 HNSW 搜索参数
“我们的结果不够相关,或者计算时间太长。” |
有时用户未能正确平衡 HNSW 搜索参数。将 HNSW 的 ef
参数设置为非常低的值(例如零)将导致极快的响应(大约一毫秒),但结果质量会很差。
❓ 用例:一位客户在他们接近 8 亿向量的庞大数据集上运行高级相似性搜索。最初,他们发现查询需要 10 到 20 秒不等的时间,尤其是在结合多个过滤器和元数据字段时。
✅ 他们如何才能在保持准确性的同时提高速度?答案是优化。
图 1: Qdrant 具有高度可配置性。您可以根据速度、精度或资源使用情况进行配置。
通过调整 ef
参数,团队找到了一个最佳点,可以实现亚秒级的响应,同时保持较高的准确性。他们还对数据库的其他方面进行了微调,例如将量化后的向量放入 RAM,同时将原始未压缩的向量卸载到磁盘。
这种策略平衡了内存使用和性能:只有紧凑的向量需要驻留在内存中以进行快速查找,而较大的向量则保留在磁盘上,直到需要时再加载。
使用量化策略压缩数据
“我们的海量数据集占用了太多内存。” |
许多用户跳过量化,导致他们的索引占用过多 RAM 并导致性能不稳定。一些用户不愿牺牲精度,但这并非总是如此。
如果您的工作负载可以容忍嵌入精度适度下降,数据压缩提供了一种有效的方法来缩小向量大小并大幅减少内存使用。通过将高维浮点值转换为低位格式(例如 8 位标量甚至单比特表示),您可以在减少磁盘占用空间的同时,将更多的向量保存在 RAM 中。
✅ 如果您的用例允许,您应该评估并应用量化。量化能够显著提升性能并降低存储成本。
这不仅加快了大规模数据集的查询吞吐量,还降低了硬件成本和存储开销。标量量化是一种中等程度的压缩方案,而二值量化则更为极端,因此务必彻底测试每种方法对精度要求的影响。
使用量化时,您可以只将压缩后的向量存储在内存中,而将原始浮点版本保留在磁盘上以供参考。这种方法显著降低了 RAM 消耗——因为量化后的向量占用空间少得多——同时仍然允许您在需要时检索全精度向量,用于下游任务(例如重新排序)。
旁注:当 Linux 内核支持且您拥有
on_disk
向量时,您始终可以启用async_io
评分器。
阅读更多: 量化文档 |
2. 如何摄取和索引大量数据?
“当我尝试导入一个巨大的数据集时,一切都停滞不前。” |
❓ 用例:一家金融科技团队摄取了 5 亿条交易记录。最初性能尚可,但在一小时内就崩溃了。
他们开启了 HNSW 索引构建,因此每次插入都会触发完整的索引更新。不幸的是,他们的 CPU 使用率飙升,其他服务也出现了超时。
✅ 根据具体情况,我们建议在大批量上传期间禁用 HNSW 索引构建,以提高摄取和索引速度。
所有记录插入完成后,您可以一次性重建索引。考虑一个专门的摄取管道,它会批量写入并在低流量时段安排索引构建。如果您没有这样的低流量时段,您可以调整 indexing_threshold
参数,在接收更新但不触发索引构建和保持集合已索引之间找到平衡。
阅读更多: 配置向量索引 |
缓解索引瓶颈的其他解决方案
✅ 增加索引线程数:如果您使用超过 16 个核心,请考虑显式增加索引线程数。
默认情况下,Qdrant 最多使用 16 个线程进行索引,但如果您发现索引期间 CPU 未被充分利用,可以增加此数量。
✅ 使用批量进程:增加并发进程数。运行 50-60 个进程可以显著提高上传性能。仅使用一两个进程无法发挥真正的性能潜力。
对索引保持耐心:上传大型数据集后,需要等待一段时间才能完成索引构建。这是正常现象,所需时间取决于您的数据集大小。
阅读更多: 配置文档 |
当索引落后于摄取时
在渐进式流式上传和大型批量上传后,索引构建都可能暂时落后于数据摄取。
默认情况下,搜索会包含未索引的数据。然而,大量未索引的点可能会导致全量扫描,显著减慢搜索速度,可能导致较高的搜索延迟、超时和应用程序故障。
如果已索引点的最大数量始终保持较低水平,这可能不是问题。如果您预计会出现大量未索引点的情况,应采取措施防止生产环境中的搜索中断。
一种选择是在搜索请求中设置 indexed_only=true
。这将通过仅考虑已索引数据来确保快速搜索,但这会牺牲最终一致性(新数据仅在索引后才可搜索)。
或者,您可以在低流量时段执行批量向量上传,以便在流量增加之前完成索引构建。
已索引点数量持续增加表明存在问题。潜在的解决方案包括:增加硬件资源,优化索引(例如,更小的段,HNSW 调优),或减少数据更改量。
阅读更多: 索引文档 |
如何安排元数据和模式以确保一致性
“我的过滤器每次的工作方式都不一样。” |
在某些情况下,载荷(payload)模式在不同的数据管道中不一致,导致某些字段类型不匹配或完全缺失。
❓ 用例:一家医疗保健公司发现,有些管道插入的是字符串,而另一些插入的是整数。过滤器悄无声息地失效或返回不一致的结果,这表明统一的载荷模式并未到位。
当摄取管道中的载荷字段类型不一致时,过滤器可能会以不可预测的方式失效。
例如,有些服务可能将“status”字段写入为字符串(“active”),而另一些服务将其插入为数字代码(1)。结果是,期望统一数据的查询可能会静默失败、跳过重要记录或产生不正确的排序/过滤结果。
✅ 确保您的载荷模式得到一致执行,无论是通过严格的类型检查还是定义明确的数据契约,都是防止这种不匹配的最佳方法。在摄取过程中记录任何模式违规行为也很重要,这让您有机会在错误影响查询性能和结果质量之前进行修复。
阅读更多: 载荷文档 |
决定如何设置多租户集合
❓ 用例:在实现向量数据库时,医疗保健机构需要确保用户数据之间的隔离。我们的客户需要确保当他们过滤查询以仅显示特定患者的文档时,查询结果中不会出现其他患者的文档。
✅ 如果可能,您几乎总是应该将租户合并到单个集合中,并按租户进行标记。
PUT /collections/{collection_name}/index
{
"field_name": "group_id",
"field_schema": {
"type": "keyword",
"is_tenant": true
}
}
图:对于多租户设置,为每个租户启动一个新集合会增加开销。多租户设计——使用带有租户字段的单个集合——更有效地利用资源。
别忘了:您始终可以在 Qdrant Cloud 中创建 API 密钥(或在开源版本中使用 JWT),通过载荷约束来强制执行特定的过滤器。
阅读更多: 多租户文档 |
3. 扩展数据库和优化资源的最佳方法是什么?
“我的 Qdrant 集群需要多少节点、CPU、RAM 和存储?” |
这取决于情况。如果您刚开始使用,我们在网站上准备了一个工具来帮助您计算。欲了解更多信息,请参阅容量规划文档。
✅ 使用 sizing calculator(容量计算器)或进行性能测试,以确保节点规格(RAM/CPU)与您的工作负载相匹配。
高估会浪费资源,而低估会导致查询缓慢或内存不足错误。通过有条理地测试实际工作负载,您可以自信地将硬件规格与您的目标摄取速率、查询量和数据集大小相匹配。
为生产环境中的高可用性场景做准备
✅ 使用至少 3 个节点以确保故障转移并降低停机风险。
三节点设置提供了容错基线:如果一个节点下线,剩余两个节点可以继续服务查询并维持数据一致性的法定人数。这可以防止硬件故障、滚动更新和网络中断。少于三个节点会使您容易受到单点故障的影响,从而可能导致整个集群下线。
我们遵循 Raft 协议,所以请查阅文档了解其重要性。
✅ 设置复制因子至少为 2,以便在节点故障时仍能保持可用性。
PUT /collections/{collection_name}
{
"vectors": {
"size": 300,
"distance": "Cosine"
},
"shard_number": 6,
"replication_factor": 2
}
复制确保数据的每个部分都存储在多个节点上。如果一个节点发生故障,另一个副本可以接管服务读写请求。这可以防止数据丢失,并为关键应用程序保持不间断的服务。复制因子设置为 2 或更高对于生产工作负载尤其重要,因为生产环境对正常运行时间和可靠性要求极高。
✅ 将生产环境与开发/暂存环境隔离——使用单独的集群,避免“吵闹的邻居”效应。
开发和暂存环境经常运行实验性构建、测试或模拟,这些活动可能导致资源使用率出现不可预测的峰值。将它们与生产环境并排运行可能会降低性能和稳定性,影响真实用户。通过在专用集群上托管生产环境,您可以保护关键工作负载免受开发活动引起的性能下降,并确保更一致、可靠的性能。
处理不平衡或过载的节点
“我的一个节点的工作量比其他节点多得多。” |
❓ 用例:一个 SaaS 平台增加了数百名新客户。突然间,延迟急剧增加,因为一个节点处理的负载是其他节点的 5 倍。特定的分片方案将某些“热”数据导向了同一个分片。
用户很可能在一个节点上拥有多个分片,这些分片最终处理了大部分流量,而其他节点则利用率不足。
在这种情况下,您应该根据节点数量和预期的 RPS(每秒请求数)选择合适的分片数量。
您需要实现一种与实际使用模式相符的分片策略。首先,将您的分片分布到所有可用节点上。这将有助于更有效地平衡负载。重新分发分片后,运行性能测试,查看它如何影响您的系统。然后添加副本并再次测试,看看性能如何变化。
您的分片策略还取决于您有多少个集合。单个集合更容易平衡,因为需要移动/平衡的东西更少。此外,单个集合的开销/协调也最少。
如何分片?
正确的分片需要考虑数据分布和查询模式。默认情况下,如果查询总是覆盖整个数据集,则分片会随机分配以实现均匀分布。如果某些租户或地理区域面临巨大的流量冲击,您可能需要按集群、按载荷(租户 ID)或自定义分片分布进行分区。
阅读更多: 分片文档 |
通过向上或向下扩展来管理您的成本
有些团队在白天流量高峰期进行扩容,然后在夜间缩容以节省资源。如果您这样做,请确保数据已正确分片和复制,这样扩容和缩容才不会导致服务降级。
如果您使用 Qdrant Cloud,您也可以通过调整复制因子(Replication Factor)来实现这一点,尽管这可能被视为一种权宜之计。
如果您有 3 个节点,只有 1 个分片,并且复制因子为 6。它将创建该分片的 3 个副本(每个节点一个),因为它无法承载更多副本。如果您在高峰时段增加 3 个节点,它将自动将该分片再复制 3 次,以尝试匹配复制因子 6。
如果您再次缩容,多余的副本将被丢弃。
✅ 在集群扩容后重新分片集合,以重新平衡数据并避免内存不足(OOM)问题。
当您向集群添加节点时,现有副本会与新分片进行自身再平衡,但数量是固定的——这可能无法充分利用新硬件的优势。结果是,原始节点仍然过载,而新节点大部分处于空闲状态。通过在扩容后对集合进行重新分片,您可以将数据均匀地分布到整个集群,从而防止过载节点上出现热点,避免导致内存不足(OOM)的情况。
如果新节点加入后仍然为空,则会浪费资源。如果离开的节点留下了未迁移的数据,则存在部分覆盖甚至数据丢失的风险。
注意:此功能仅在 Qdrant Cloud 以及混合云和私有云中可用,自托管时不可用。
如何预测和测试集群性能
“我直到为时已晚才知道出了问题。” |
此类问题往往发生在用户未监控资源使用、搜索性能或安全性时。在用户投诉之前,严重故障未被发现。
✅ 在预期的流量条件下运行负载测试,以便在上线前识别瓶颈。
您需要制定一个计划,在负载测试中使用真实数据。理想情况下,您应该使用与实际工作负载高度相似的生产流量或历史数据进行测试。与随机生成的测试数据相比,这能提供更准确的结果,因为它能更好地代表真实世界的使用模式和数据分布。
设计您的负载测试,逐步增加流量,直到达到或超过您预期的生产负载。例如,如果您预计生产环境中的 RPS(每秒请求数)为 1000,则可以增量地扩展测试以达到此阈值,同时监控延迟。响应将分别显示服务器时间,以便进行细粒度监控。
您应该在重启后测试系统性能,以了解冷启动行为。重启后的初始查询可能会显著变慢,因为需要重建缓存。例如,一个查询最初可能需要 50-60 秒,但在后续运行中只需要 0.5 秒。
请记住,冷启动和查询行为取决于数据集,因此您应该建立自己的基线并了解预期情况。
阅读更多: 分布式部署文档 |
如何设计系统以防范故障
“当一个节点崩溃时,我们的整个集群都宕机了。” |
不幸的是,您没有为故障转移或混沌测试做计划,因此单点故障导致了生产中断。您应该通过冗余存储数据、测试故障转移和运行混沌实验来计划应对硬件或节点崩溃。
✅ 定期测试故障,以揭示您的系统如何恢复。
高并发和大量内存占用可以更快地暴露配置错误,因此定期模拟故障可以揭示系统如何恢复。
- 优雅的节点关机:排空查询,通过负载均衡器重新分配分片所有权。
- 冗余数据路径:将数据存储在多个卷或多个位置。
- 负载测试:生成高并发或大量查询,模拟真实的流量高峰模式。
设置遥测以便及早检测
❓ 用例:一家医疗保健领域的客户使用其 Qdrant 部署产生的遥测数据来识别开源实现的性能和扩展问题。遥测数据帮助他们监控搜索性能、RAM 利用效率和索引速度等指标。通过分析这些数据,他们可以努力降低查询响应时间并优化系统配置。
✅ 启用遥测和监控,以便您可以跟踪延迟、吞吐量和优化统计数据。
遥测至关重要。您需要收集搜索延迟分布、CPU 使用率、磁盘吞吐量和内存消耗等指标。如果在索引构建期间内存使用率达到 90%,那 clearly 表明您需要更多容量或更多节点。
构建仪表盘以监控 CPU 使用率、内存消耗、磁盘 I/O 和索引速度,这有助于您发现资源瓶颈。否则,您只有在延迟急剧增加或日志充满错误时才会发现问题。
监控什么?
对于检索,应关注 P99 延迟指标(最慢的 1% 请求的响应时间),而不仅仅是平均延迟。这让您更好地了解最差情况下的性能。
对于硬件,在测试期间监控资源利用率。如果您未看到预期的 CPU 利用率(例如,8 个 CPU 中只有 2 个在使用),则可能存在限制性能的配置问题。测试不同的配置以找到适合您的特定工作负载的最佳设置。
图:如果您正在将监控、网络和日志指标抓取到您自己的监控系统中,您可以使用我们的 Grafana 仪表盘来可视化这些指标。
包含结合读写操作的测试,以模拟实际使用情况。例如,您可以配置一个测试,其中 80% 为读操作,20% 为写操作,以匹配您预期的生产工作负载。
通过遵循这些全面的负载测试实践,您将能够在系统上线前识别并解决潜在的瓶颈,从而确保更顺利的上线和更好的用户体验。
4. 通过数据库备份和快照确保灾难恢复
“我试图恢复快照,结果现在一切都坏了。” |
❓ 用例:一家数字出版商遭遇了灾难性宕机,并试图从备份恢复。直到部分数据丢失后,他们才发现了索引格式不匹配的问题。另一家公司则发现,在高峰流量期间快照压缩占用了大量 CPU,导致查询性能下降。
不幸的是,我们的一些用户从未测试过备份,因此他们在最糟糕的时候——恢复期间,才发现了版本不匹配或部分/增量备份丢失数据的问题。
完整备份还是快照恢复?
对于灾难恢复场景,您应该使用完整备份而非快照。快照主要用于集群间移动数据,而备份旨在恢复集群的完整状态。
图:在 Qdrant Cloud UI 中配置集群备份
完整备份会复制整个数据集,包括索引和其他配置。这对于完整性很好,但可能成本较高且耗时。完整快照恢复速度更快,但协调和恢复整个状态更为复杂。
快照很方便,因为它们可以创建集合的存档,或者更细粒度地说,创建分片的存档,您可以下载并上传到另一个实例。如果您不想经历漫长的索引过程,可以使用此功能。
✅ 设置定期快照或备份,并验证在需要时可以恢复。
无论您选择哪种方式,务必始终测试恢复过程。有些团队直到真正的灾难发生时,才意识到备份是不完整的或损坏的。
备份大型部署的最佳方法
如果您托管着数百亿个向量,请将备份存储在节点外部,位于不同的数据中心或远程仓库中。此外,请确认您的恢复带宽是否足够。如果恢复管道比本地磁盘慢,恢复时间将远远超出预期。
为避免恢复后出现版本不匹配的情况,请始终保留索引配置,例如量化设置或 HNSW 参数。
5. 数据库管理的实用技巧
“我总是内存不足,服务崩溃。” |
您很可能没有为数据库分配足够的 CPU 和内存,或者没有将硬件资源与并发级别匹配。因此,系统在重负载下会发生抖动或终止。
❓ 用例:一家中型电商公司试点了向量搜索解决方案,以改善产品发现。在测试中一切运行顺利,但一旦投入生产,内存错误、磁盘 I/O 飙升和查询延迟问题层出不穷。
调查显示,他们没有调整默认配置或为预写日志保留专用存储。由于 RAM 不足,他们的索引反复溢出到磁盘,损害了性能。
✅ 分配与您的数据量和并发需求相匹配的内存和 CPU
向量数据库需要仔细的资源管理。如果内存、CPU 和磁盘设置与实际工作负载不匹配,您将在高峰负载下遇到随机的性能下降或部分故障。有时表现为不可预测的延迟。其他时候,您会看到严重的资源争用,导致 CPU 或磁盘饱和。
注意:CPU 不足可能只会降低速度。内存不足可能导致系统崩溃。
阅读更多: Qdrant 配置文档 |
安全与治理
用例:一家制造公司创建了一个依赖于许多组织组件的“超级聊天机器人”。该公司需要确保其应用程序组件之间的安全通信——数据传输至关重要。
✅ 在生产环境中启用 TLS/HTTPS 以进行加密通信。
启用 TLS/HTTPS 对于满足受监管行业的合规性要求至关重要。对于重视数据隐私和安全的公司(例如金融、政府和医疗保健领域的公司)来说,这种安全级别至关重要,有助于克服潜在的安全团队反对意见。
您需要保护传输中的数据。要在生产环境中为加密流量启用 TLS/HTTPS,您需要配置客户端与 Qdrant 数据库以及各个集群节点之间的安全通信。这包括实施传输层安全 (TLS) 证书来加密所有流量,防止未经授权的访问和数据拦截。
如果是自托管,您可以通过直接从配置中启用 TLS来设置加密。
service:
# Enable HTTPS for the REST and gRPC API
enable_tls: true
# TLS configuration.
# Required if either service.enable_tls or cluster.p2p.enable_tls is true.
tls:
# Server certificate chain file
cert: ./tls/cert.pem
# Server private key file
key: ./tls/key.pem
阅读更多: 安全文档 |
在生产环境中设置访问控制
用例:一家大型企业需要在其 Qdrant 数据库中实施访问控制,例如“团队 A 只能访问集合 A、B 和 C,而不能访问集合 D”。
✅ 设置基于角色的访问控制 (RBAC),以限制用户或服务的操作。
用户可以通过角色详情页面邀请并关联到特定角色——只需点击用户选项卡并按照提示操作即可。一旦接受邀请,他们将被分配该角色的权限,以及基础角色权限。
图:Qdrant Cloud 中数据库的基于角色的访问控制界面
✅ 使用范围化的 API 密钥或身份验证令牌,以避免服务权限过度。
对于他们的私有云实现,他们手动设置了 JWT 令牌。他们将这些 JWT 令牌集成到现有的基于角色的访问控制系统中。他们创建了具有特定角色、职责和从其 SSO 系统派生的标签的令牌。这使得他们能够在多个层面控制访问,包括多租户和通过元数据字段进行访问。
✅ 配置访问权限时遵循最小权限原则——只授予绝对必要的权限。
对于 Qdrant 托管云服务的用户,可以直接通过用户界面配置 RBAC,这会自动创建基于角色的访问控制,无需手动配置 JWT。
阅读更多: 云 RBAC 文档 |
记住要避免这些常见陷阱
❌ 不要忘记索引载荷字段——不这样做会减慢您的搜索速度。
❌ 不要不配置复制运行——单节点设置非常脆弱。
❌ 不要为每个用户/客户创建一个集合——使用多租户功能。
❌ 不要将对延迟敏感的搜索与重量级批处理作业一起运行——将工作负载分开。
❌ 不要跳过量化——它能大幅减少内存占用并加快搜索速度。
❌ 不要使用过时的 Qdrant 版本——定期更新。
结论
总之,生产环境中的向量搜索并不局限于特定的云提供商或基础设施。仔细的配置、稳健的摄取/索引、智能的扩展、全面的备份、强大的可观察性和安全性等核心原则普遍适用。通过掌握这些基本要素,无论您的硬件或服务运行在哪里,您都能为用户提供快速、可靠且可扩展的搜索。