返回 Qdrant 内部结构

为向量搜索而生

Evgeniya Sukhodolskaya & Andrey Vasnetsov

·

2025年2月17日

Built for Vector Search

任何稍有复杂性的问题都需要专门的解决方案。你可以用瑞士军刀开瓶或在纸板箱上戳个洞,但你需要一把斧头来劈柴——软件也是如此。

在本文中,我们将描述向量搜索带来的独特挑战,以及为什么专用解决方案是解决这些挑战的最佳途径。

向量

vectors

让我们来看看向量数据库的核心概念——向量

向量(也称为嵌入)是各种数据点(文本、图像、视频等)的高维表示。许多最先进(SOTA)的嵌入模型生成的表示维度超过1,500。对于最先进的PDF检索,表示的维度可以达到每页超过100,000维

这就引出了向量搜索的第一个挑战——向量很“重”。

向量很“重”

从这个角度来看,考虑存储在关系数据库中的一百万条记录。这对于现代数据库来说是一个相对少量的数据,许多云提供商的免费层都可以轻松处理。

现在,使用OpenAI的text-embedding-ada-002模型从每条记录生成一个1536维的嵌入,你需要大约6GB的存储空间。因此,向量搜索工作负载,特别是在未优化的情况下,会很快占据非向量数据库的主要用例。

将向量作为主数据库的一部分还存在另一个潜在问题——向量始终是其他数据的转换。

向量是一种转换

向量是从其他真实数据源获取的。如果丢失,可以使用之前使用的相同嵌入模型恢复。同时,即使该模型发生微小变化,也可能改变向量空间的几何结构,因此如果您更新或更改嵌入模型,则需要更新并重新索引所有数据,以保持准确的向量比较。

如果与主数据库耦合,此更新过程可能导致严重的复杂性,甚至整个系统不可用。

然而,向量也具有积极的特性。其中最重要的一点是向量是固定大小的。

向量是固定大小的

嵌入模型被设计成产生固定大小的向量。我们必须利用这一点优势。

为了快速搜索,向量需要即时可访问。无论是在RAM还是磁盘中,向量都应以允许快速访问和比较的格式存储。这至关重要,因为向量比较是向量搜索工作负载中非常频繁的操作。每次搜索查询通常会执行数千次,因此即使是很小的开销也可能导致显著的速度下降。

对于专用存储,向量的固定大小是一大优势。知道一个数据点需要多少空间,我们就不必处理定位数据的通常开销——存储中元素的位置很容易计算。

如果向量与其他数据类型(例如文本或JSON)一起存储,一切都会变得不那么直观。单个数据点的大小不再固定,因此访问它变得非易事,尤其是在数据随时间推移不断添加、更新和删除的情况下。

Fixed size columns VS Variable length table

固定大小列 VS 可变长度表

将向量与其他类型的数据一起存储,我们会失去其特性带来的所有好处;然而,我们会充分“享受”它们的缺点,用存储中已存在的数据的极重转换来污染存储。

vector-search

与充当数据存储的传统数据库不同,向量数据库更像搜索引擎。它们被设计成可扩展、始终可用,并且即使在高负载下也能提供高速搜索结果。正如Google或Bing可以同时处理数十亿次查询一样,向量数据库被设计用于必须进行快速、高吞吐量、低延迟检索的场景。

Database Compass

数据库指南针

任选其二

分布式系统非常适合可扩展性——这些系统中的水平扩展允许您根据需要添加更多机器。在分布式系统的世界里,一个众所周知的原则——CAP定理——说明了你不可能拥有一切。该定理指出,分布式系统只能保证三项属性中的两项:一致性(Consistency)可用性(Availability)分区容错性(Partition Tolerance)

由于网络分区在任何真实的分布式系统中都不可避免,所有现代分布式数据库在设计时都考虑了分区容错性,这使得在一致性(提供最新数据)和可用性(保持响应)之间必须进行权衡。

在这种背景下,数据库有两种主要的设计理念

ACID:优先考虑一致性

ACID模型确保每个事务(被视为单个单元的操作组,例如账户间的资金转移)要么完全执行,要么完全不执行(回滚),从而使数据库处于有效状态。当系统是分布式的时,实现ACID属性需要节点之间复杂的协调。每个节点必须就事务的状态进行通信和达成一致,这可能限制系统的可用性——如果一个节点不确定另一个节点的状态,它可能会拒绝处理事务,直到确保一致性。这种协调也使得扩展更具挑战性

金融机构在处理资金转移时使用符合ACID的数据库,在这种情况下,即使是账户余额的瞬间差异也是不可接受的。

BASE:优先考虑可用性

另一方面,BASE模型倾向于高可用性和分区容错性。BASE系统将数据和工作负载分布到多个节点上,使其能够立即响应读写请求。它们遵循最终一致性原则——尽管数据可能暂时不是最新的,但系统会随着时间的推移收敛到一致状态。

社交媒体平台、流媒体服务和搜索引擎都受益于BASE方法。对于这些应用,即时响应能力比严格一致性更为关键。

考虑到向量搜索的特性——其本质要求可用性&可扩展性——它应该基于BASE架构提供服务。做出此选择是因为需要水平扩展、高可用性、低延迟和高吞吐量。例如,基于BASE的架构使我们能够轻松管理重新分片

当我们记住向量是我们可支配数据的重量级转换时,严格一致的事务处理方法也失去了吸引力——如果我们可以通过转换随时恢复向量化数据,那么限制数据保护机制有什么意义呢?

向量索引

vector-index

向量搜索依赖于高维向量数学,这使得它在大规模应用中计算量巨大。暴力相似性搜索需要将查询与数据库中的每个向量进行比较。在一个拥有1亿个1536维向量的数据库中,每次查询执行1亿次比较在生产场景下是不可行的。向量数据库不采用暴力方法,而是拥有专门的近似最近邻(ANN)索引,可在搜索精度和速度之间取得平衡。这些索引需要精心设计的架构,以便在生产环境中进行维护。

HNSW Index

HNSW 索引

最流行的向量索引之一是HNSW(Hierarchical Navigable Small World,分层可导航小世界),我们选择它是因为它能够同时提供高搜索速度和准确性。高性能是有代价的——由于存在一些挑战,在生产环境中实现它并非易事,因此为了让它发挥最佳效果,整个系统架构必须围绕它构建,服务于这个“反复无常”的索引。

索引复杂度

HNSW被构建为多层图。插入新的数据点时,算法必须将其与跨多个层的现有节点进行比较才能进行索引。随着向量数量的增长,这些比较会显著减慢构建过程,使得更新越来越耗时。索引操作可能很快成为系统中的瓶颈,减慢搜索请求。

构建一个HNSW单体意味着限制了解决方案的可扩展性——其大小必须受到限制,因为其构建时间与元素数量呈非线性关系。为了保持构建过程的可行性并确保其不影响搜索时间,我们提出了一种分层架构,将所有数据管理分解为称为段(segments)的小单元。

Storage structure

存储结构

每个段隔离一部分向量化语料库,并支持对其进行所有集合级别操作,从搜索到索引,例如段在其可用的数据子集上构建自己的索引。对于在集合级别工作的用户来说,分段的细节是不可见的。他们获得的搜索结果跨越整个集合,因为子结果是从各个段中收集,然后合并&去重。

通过平衡段的大小和数量,我们可以确保搜索速度和索引时间之间的适当平衡,使系统能够灵活应对不同的工作负载。

不可变性

通过在段之间划分索引维护,Qdrant即使在高负载下也能确保高性能,并且额外的优化进一步保障了这一点。这些优化源于一个理念:使用不可变结构带来了很多好处:可以使用内部固定大小的列表(因此无需动态更新),根据访问模式对存储数据进行排序(因此没有不可预测的随机访问)。考虑到这一点,为了进一步优化搜索速度和内存管理,我们采用了一种结合和管理可变段和不可变段的策略。

可变段这些用于快速摄取新数据以及处理现有数据的更改(更新)。
不可变段一旦可变段达到特定大小,优化过程会将其转换为不可变段,并构建HNSW索引——您可以在此处详细阅读有关这些优化器的信息。例如,这种不可变性技巧使我们能够确保有效的租户隔离

不可变段对用户来说是一个透明的实现细节——他们可以随时删除向量,而添加和更新则应用于可变段。这种可变性和不可变性的结合使得搜索和索引可以在高负载下同时平稳运行。这种方法最大程度地减少了索引时间对性能的影响,并允许在集合级别动态更改配置(例如启用或禁用数据量化)而无需停机。

可过滤索引

向量搜索在历史上并非为过滤而设计——即对结果施加严格限制。它本质上是模糊的;在某种程度上,每个文档都与任何查询既相似又不相似——没有二进制的“符合/不符合”区分。因此,向量搜索算法最初构建时并没有考虑到过滤。

同时,过滤在许多向量搜索应用中是不可避免的,例如电商搜索/推荐。搜索圣诞礼物时,你可能想过滤掉所有价格超过100欧元的东西,同时仍然受益于向量搜索的语义特性。

在许多向量搜索解决方案中,过滤有两种方法:前过滤(pre-filtering)(在运行HNSW搜索之前计算所有符合条件的向量的二进制掩码)或后过滤(post-filtering)(照常运行HNSW,然后过滤结果)。

前过滤计算向量掩码的复杂度是线性的,对大型数据集来说会成为瓶颈。
后过滤后过滤的问题与向量搜索“一切都符合,同时又不符合”的特性有关:想象一个低基数的过滤器,它在数据库中只留下少量匹配元素。如果它们中没有一个与查询足够相似,能够出现在前X个检索结果中,那么它们都将被过滤掉。

Qdrant在向量搜索过滤方面走得更远,认识到前过滤&后过滤策略的局限性。我们开发了HNSW的一个改进版本——可过滤HNSW——它还可以在图遍历期间实现原地过滤(in-place filtering)。为了实现这一点,我们在HNSW索引构建时考虑了可能的过滤条件,这些条件通过Payload索引(基于向量元数据构建的倒排索引)来反映。

Qdrant设计之初就将向量索引作为系统的核心组件。这使得围绕向量索引组织优化器、Payload索引和其他组件成为可能,从而解锁了构建可过滤HNSW的可能性。

Filterable Vector Index

可过滤向量索引

总的来说,优化向量搜索需要对数据和索引管理采用定制化的、精细调整的方法,以确保即使数据动态增长和变化时也能保持高性能。这种专用架构是专用向量数据库在生产环境中总是优于通用数据库的关键原因。

超越RAG的向量搜索

Vector Search is not Text Search Extension

向量搜索不是文本搜索的扩展

许多关于向量数据库用途的讨论集中在检索增强生成(Retrieval-Augmented Generation, RAG)——或其更高级的变体,agentic RAG——其中向量数据库被用作知识源,为大型语言模型(LLMs)检索上下文。这是一个正当的用例,然而,RAG解决方案的炒作浪潮掩盖了向量搜索更广泛的潜力,它超越了增强生成式AI

发现

向量搜索的优势在于它能够促进发现。向量搜索允许您在搜索过程中细化选择,而不是从固定的查询开始。比如说,您在点餐时并不完全知道自己想要什么——只知道它应该包含肉&而不是汉堡,或者它应该是有肉和芝士&而不是墨西哥卷饼。向量搜索不是搜索特定的菜肴,而是帮助您根据相似性和不相似性浏览选项,引导您找到符合您口味的东西,而无需您预先明确定义它。

推荐

向量搜索非常适合推荐。想象一下浏览新书或电影。您可能不会搜索完全匹配的内容,而是寻找捕捉特定情绪或主题,但在关键方面与您已知内容不同的故事。例如,您可能想要一部以巫师为主题的电影,但又不想有《哈利·波特》系列的熟悉感。这种灵活性之所以可能,是因为向量搜索不局限于二元的“匹配/不匹配”概念,而是在向量空间中基于距离进行操作。

大规模非结构化数据分析

向量搜索的特性也使其成为大规模非结构化数据分析的理想选择,例如异常检测。在大型、非结构化且通常未标记的数据集中,向量搜索可以通过分析数据点之间的距离关系来帮助识别聚类和异常值。

根本不同

超越RAG的向量搜索不仅仅是另一个功能——它是我们与数据交互方式的根本转变。专用解决方案原生集成了这些功能,并且从头开始设计用于处理高维数学和基于(不)相似性的检索。相比之下,带有向量扩展的数据库是围绕不同的数据范例构建的,这使得它们无法有效地支持高级向量搜索功能。

即使您想改造这些能力,这也不仅仅是添加新功能的问题——这是一个结构性问题。支持高级向量搜索需要专用接口,以实现从多阶段过滤到高维空间动态探索的灵活向量搜索用法。

当底层架构最初并非为此类交互而设计时,集成接口对软件工程团队来说是一场噩梦。最终你会打破现有假设,被迫采用低效的权宜之计,并经常引入向后兼容性问题。这就是为什么试图将向量搜索“打补丁”到传统数据库上的效率无法与专用系统媲美的原因。

使向量搜索达到最先进水平

vector-search-state-of-the-art

现在,让我们将重点转向专用解决方案的另一个关键优势——它们能够跟上该领域最先进解决方案的能力。

向量数据库是专为向量检索而构建的,因此它们提供了对于依赖向量搜索的AI企业至关重要的尖端功能。向量数据库工程师投入大量时间和精力研究和实现执行向量搜索的最优方法。许多这些创新对于原生向量架构来说是自然的,而添加了向量功能的通用数据库可能难以有效适应和复制这些优势。

考虑Qdrant中实现的一些高级功能

  • GPU加速索引
    通过将索引构建任务卸载到GPU,Qdrant可以显著加快数据索引过程,同时保持较低成本。这在处理热数据场景下的大型数据集时尤其有价值。

    Qdrant中的GPU加速是由我们核心团队的一位爱好者开发的定制解决方案。它是非供应商依赖的,并原生支持Qdrant所有独特的架构特性,从可过滤HNSW到多向量。

  • 多向量
    一些现代嵌入模型输出的是整个矩阵(向量列表),而不是单个向量。Qdrant原生支持多向量。

    此功能在使用最先进的检索模型(例如ColBERT、ColPali或ColQwen)时至关重要。例如,ColPali和ColQwen产生多向量输出,原生支持它们对于最先进(SOTA)的PDF检索至关重要。

除此之外,我们还不断寻求以下方面的改进

内存效率 & 压缩使用量化HNSW压缩等技术来减少存储需求
检索算法支持最新的检索算法,包括稀疏神经网络检索混合搜索方法和重排器(re-rankers)
向量数据分析 & 可视化距离矩阵API等工具提供了对向量化数据的洞察,而Web UI则允许直观地探索数据。
搜索速度 & 可扩展性包括针对多租户环境的优化,以确保高效且可扩展的搜索。

这些进步不仅仅是增量改进——它们定义了为向量搜索优化的系统与仅适应向量搜索的系统之间的区别。

站在向量搜索的最前沿不仅仅关乎性能——也关乎跟上不断发展的AI格局。

总结

conclusion-vector-search

在向量搜索方面,使用专用向量搜索解决方案与扩展数据库以支持向量操作之间存在明显区别。

对于处理不超过一百万数据点的小规模应用或原型,未优化的架构可能足够。然而,随着向量数量的增长,未优化的解决方案将迅速成为瓶颈——减慢搜索操作并限制可扩展性。专用向量搜索解决方案从头开始设计,旨在高效处理大量高维数据。

最先进(SOTA)的向量搜索发展迅速。如果您打算基于最新进展进行构建,使用向量扩展最终会阻碍您。专用向量搜索解决方案原生集成这些功能,确保您在不影响性能的情况下受益于持续创新。

向量搜索的力量延伸到大数据分析、推荐系统和基于发现的应用等领域,而要支持这些向量搜索能力,需要一个专用解决方案。

何时选择专用数据库而非扩展

  • 高流量、实时搜索:非常适合需要许多同时在线用户快速、持续访问搜索结果的应用——例如搜索引擎、电商推荐、社交媒体或媒体流服务。
  • 动态、非结构化数据:非常适合数据不断变化且目标是从数据模式中发现洞察的场景。
  • 创新应用:如果您正在寻求实现推荐引擎、混合搜索解决方案或探索性数据分析等高级用例,而传统精确或基于Token的搜索能力不足时。

如果您的应用依赖于大规模向量搜索、需要跟上趋势或不仅仅是简单的SOTA小规模相似性搜索,那么投资专用向量搜索引擎将提供成功所需的性能和灵活性。

本页面有用吗?

感谢您的反馈!🙏

很抱歉听到这个消息。😔 您可以在GitHub上编辑此页面,或创建一个GitHub issue。