背景
现在的数据分为20%的传统结构化数据,80%的非结构化数据
结构化数据:主要单元是数值与符号,数据类型高度抽象且易于组织。基于数值运算与关系代数,可以轻松地对结构化数据进行分析。
非结构化数据:常见的类型包括文本、图像、音频、视频,也包括领域相关的类型,如病毒代码、社交关系、时空数据、化合物结构、点云等。
传统的数据分析方法难以挖掘非结构化数据的信息,但是通过Embedding技术来向量化数据为我们提供了理解非结构化数据的途径。
向量化的数据层具有一系列很好的性质:
(1)Embedding 向量是一种抽象的数据类型,针对抽象的数据类型可以构建统一的代数系统,从而避免非结构化数据丰富的形态所带来的复杂性;
(2)Embedding 向量的物理表示是一种稠密的浮点数向量,这有助于利用现代处理器的 SIMD 能力提升数据分析速度,降低平均算力成本;
(3)Embedding 向量这种信息编码形式,通常比原始的非结构化数据要小得多,占用存储空间更低,并能提供更高的信息传输效率。
(4)Embedding 向量也有与其对应的算子系统,最常用的算子是语义近似匹配。下图给出了一个跨模态语义近似匹配的例子。需要注意的是,图中给出的是匹配的结果。在具体运算过程中,文字和图片都会被映射到同一个 Embedding Space,在这个空间内进行向量化的语义近似分析。
除此之外,还有语义上的加法操作,如图所示。
除了上述玩具性的功能,在实际应用场景中,这些算子还可以支持很复杂的查询语句。推荐系统是一个比较典型的例子,它所用到的数据主要是用户行为、内容两大类。通常会对每个内容及用户的浏览偏好进行 embedding,通过对用户偏好与内容间的向量进行语义相似度分析。除此之外,向量数据层上的应用还包括电商、病毒代码检测、数据去重、生物特征验证、化学分子式分析、金融、保险等。
无针对非结构化数据的基础软件栈
传统的数据库、数据分析引擎,主要都是服务于结构化数据。
与传统的数据库系统相比,向量数据库作用于不同的数据层。传统的数据库,如关系数据库、KV 数据库、文本数据库、图像/视频数据库都作用于原始数据层,而 Milvus 则作用于其上的向量化数据层,解决 Embedding 向量的存储与分析问题。
向量数据库的主要特性
基本能力
向量的存储、检索和分析;提供标准的访问接口,具备数据插入查询删除更新的能力
高效支持向量算子
分析引擎中对向量算子的支撑主要在两个层面:
(1)算子类型:如上述的“语义相似性匹配”、“语义上的加法”等算子
(2)对相似性度量的支持:向量算子在底层执行的过程中都需要对“相似性”进行有效度量。这种相似性通常会被量化到空间上数据之间的距离,常见的距离量化方式包括欧式距离、余弦距离、内积距离等。
补充:算子是数学中一个非常重要的概念,它通常指的是一个将数学对象(如数字、函数、矩阵等)映射到另一个数学对象的规则或函数。在数学的不同分支中,算子的定义和用途可能有所不同,但它的核心思想是相同的——算子描述了一种转换或操作。
向量索引能力
相比传统数据库基于 B 树、LSM 树等结构索引,高维向量索引往往计算量更大,属于计算密集型场景。
索引算法层面:多采用聚类、图等技术。
运算层面:以矩阵运算、向量为主。因此,充分挖掘现代处理器的向量加速能力,对于降低向量数据库的算力成本至关重要。
跨部署环境
向量数据库通常会有不同的部署环境,这是由数据科学流程决定的。在前面阶段,数据科学家、算法工程师用系统主要是笔记本或工作站,因为他们关注验证速度和迭代速度。验证好后就需要部署,这就对应着私有集群或云上的大规模部署。因此,需要在不同的部署环境中都能让系统具备良好的表现。
支持混合查询
近年来,随着向量数据库的不断发展,越来越多的新需求涌现出来。其中最常见的一个需求就是其他数据类型和向量混合查询,比如基于标量过滤后再执行最近邻查询,基于全文检索和向量检索相结合的多路召回,以及时空时序数据和向量数据的结合。这要求向量数据库具备更加灵活的扩展能力以及更智能的查询优化,使向量引擎可以与 KV 引擎、文本检索引擎等进行高效协作。
补充:
基于标量过滤后再执行最近邻查询:
标量过滤是一种基于特定标量的数据过滤方法,例如,我们可以使用欧几里得距离或曼哈顿距离等来过滤数据。我们首先计算数据集中每个数据点到查询点的距离,然后选择距离小于某个阈值的点作为候选邻居。这样,我们可以大大减少数据集的大小,从而提高查询效率。
在标量过滤后,我们再执行最近邻查询。最近邻查询的目标是在过滤后的数据集中找到与查询点最近的邻居。这可以通过计算查询点到过滤后的每个数据点的距离来实现,然后选择距离最小的点作为最近邻居。
基于全文检索和向量检索相结合的多路召回:
全文检索是一种基于关键词的检索方法,通过在数据集中查找包含特定关键词的文档或数据来找到相关结果。这种方法适用于处理文本数据,但对于图像、音视频等非结构化数据,全文检索的效果并不理想。
向量检索是一种基于向量表示的检索方法,将非结构化数据转换为向量表示,然后通过计算向量之间的相似度来找到与查询向量最相似的向量。这种方法在处理非结构化数据时具有较好的效果,但对于文本数据,向量检索的准确性可能不如全文检索。
基于全文检索和向量检索相结合的多路召回方法将这两种技术融合在一起,以提高检索效果。具体而言,这种方法首先使用全文检索找到包含查询关键词的文档或数据,然后使用向量检索找到与查询向量最相似的向量。最后,将这两种检索结果进行融合和重排序,以返回最终的候选列表。
云原生
随着非结构化数据规模快速增长,向量数据的体量也在不断增长,千亿规模的高维向量对应着数百 TB 级别的存储。这种存储规模远远超过了单机所能承担的范围,因此,横向扩展能力对于向量数据库而言也就变得非常重要。一个成熟的向量数据库应该满足用户对弹性和部署敏捷性的要求,借助云基础设施降低系统运维的复杂度,提升可观测性。此外,用户对于多租户隔离、数据快照和备份、数据加密、数据可视化等传统数据库能力也提出了越来越高的需求。
向量数据库的系统架构
目前,Milvus 已演进至 2.0 版本,其设计遵循日志即数据、流批一体、无状态化和微服务化的准则,整体架构设计可参见下图。
日志即数据
在 2.0 版本中没有维护物理上的表,而是通过日志持久化和日志快照来保证数据的可靠性。日志系统作为系统的主干,承担了增量数据持久化和解耦的作用。通过日志的发布-订阅机制,将系统的读、写组件解耦。如图5 所示,整个系统主要由两个角色构成,分别是**“日志序列(Log Sequence)”与“日志订阅者(Log Subscriber)”**。其中的“日志序列”记录了所有改变库表状态的操作,“日志订阅者”通过订阅日志序列更新本地数据,以只读副本的方式提供服务。发布-订阅机制的出现也给系统预留了很大的拓展空间,便于 Change data capture(CDC)、全球部署等功能的拓展。
流批一体化
借助日志流实现数据的实时更新,保证数据的实时可达。再将数据批量转换成日志快照,通过对日志快照构建向量索引实现更高的查询效率。查询时,通过合并增量数据和历史数据的查询结果,保证用户可以获取完整的数据视图。这种设计较好地满足了实时性和效率的平衡,降低了传统 Lambda 架构下用户维护离/在线两套系统的负担。
无状态化
借助云基础设施和开源存储组件,实现自身组件不需要保证数据的持久化。当前,Milvus 的数据持久化依赖三种存储,分别为元数据存储、消息存储和对象存储。常见的元数据存储如 Etcd、Zookeeper,主要负责元信息的持久化和服务发现、节点管理。消息存储如 Kafka、Pulsar,主要负责增量数据的持久化和数据的发布订阅。对象存储如 S3、Azure Blob、MinIO,主要负责用户日志快照、索引以及一些中间计算结果的存储。
微服务化
严格遵循数据流和控制流分离、读写分离、离线和在线任务分离。整体分为四个层次,分别为接入服务、协调服务、执行服务和存储服务。各个层次相互独立,独立扩展和容灾。
接入层作为系统的门面,主要负责处理客户端链接,进行请求检查和转发。
协调服务作为系统的大脑,负责集群拓扑管理、负载均衡、数据声明和管理。
执行节点作为系统的四肢,负责执行数据更新、查询和索引构建等具体操作。
存储层作为系统的骨骼,主要负责数据本身的持久化和复制。
微服务化的设计保证了可控的复杂度,每一个组件专注于相对单一的功能。通过定义良好的接口清晰地表述服务边界,更细粒度的拆分也有利于更加灵活的扩展和更精确的资源分配。
向量数据库的技术挑战
以往的研究工作主要专注于高效率向量索引结构和查询方法的设计
如今的研究工作开始从系统设计的角度去审视和思考向量查询问题,并逐渐产生了一些针对向量搜索问题系统化的解决方案
针对负载特性的成本-性能优化
由于向量数据的高维特性,其分析过程相对传统数据类型具有更高的存储和计算成本。另一方面,不同用户的向量查询负载特性以及成本-性能偏好往往是不尽相同的。例如,部分用户的数据规模巨大,达到了百亿甚至千亿级别。此类用户通常需要较低成本的数据存储方案,同时能够容忍一定的查询延迟。另外也存在一些用户对查询性能非常敏感,通常要求单条查询的延迟稳定保持在若干毫秒。为了满足不同用户的偏好,向量数据库的核心索引组件需要有能力将索引结构和查询算法与不同类型的存储和计算硬件进行适配。例如,为了降低存储成本,需要考虑将向量数据和索引结构存储在比内存更为廉价介质中(如 NVM 和 SSD)。然而,现有的向量搜索算法几乎都是基于数据可以完全驻留在内存中而设计的。为了尽量避免使用 NVM 或 SSD 带来的性能损失,需要结合搜索算法充分挖掘和利用数据访问局部性,并结合存储介质特性对数据和索引结构的存储方式进行调整(见参考资料6~8)。对于查询性能敏感的用户,目前主流的探索方向为使用 GPU、NPU、FPGA 等专有硬件加速查询过程(见参考资料9)。然而,不同加速硬件和专有芯片的结构设计均不相同,如何结合这些硬件的特性对高效地执行向量索引请求目前仍是一个尚未良好解决的问题。
智能化系统配置与调优
现有的几种主流向量查询算法都是在存储成本、计算性能以及查询准确度之间寻求不同的平衡点,算法的实际表现通常由算法参数和数据特性共同决定。考虑到用户对于向量查询成本和性能要求的差异性,如何针对用户需求以及数据特性为其选择合适的向量查询方法便成为了一个重要问题。然而,由于向量数据的高维特性,使得人工方法通常难以有效分析数据分布特性对查询算法的影响。针对这一问题,学术界和工业界目前主要尝试使用基于机器学习的方法为用户推荐合适的算法配置(见参考资料10)。另一方面,结合机器学习技术的智能向量查询算法设计也是研究的一个热门话题。当前的向量查询算法通常是在假设不知道向量数据特性的情况下进行设计的。这类算法具有较强的通用性,能够应对不同维度数量、不同分布类型的向量数据。相对应的,它们无法根据用户数据的特性进行针对性的索引结构设计,也就无法再进一步挖掘和利用其中的优化空间。如何使用机器学习方法有效地为不同用户数据量身定制索引结构是一个值得探索的重要问题
对丰富查询语义的支持
一方面对向量数据查询语义在不同应用中存在多样性,正逐渐超越传统近邻查询的范畴。另一方面,对于多个向量数据联合搜索,以及向量数据和非向量数据的综合查询需求也在逐渐产生(见参考资料13)。具体而言,对于向量数据查询,向量相似性的评价指标变得更加多样。传统的向量查询通常使用欧式距离、内积以及余弦距离作为向量的相似度指标。随着 AI 技术在各行各业的普及,一些领域特定的向量相似指标,如谷本距离、马氏距离以及用于计算化学分子超结构和子结构的距离指标正逐渐涌现。如何在现有的查询算法中有效地支持这些评价指标或相应地设计新型的检索算法成为了亟待研究的重要问题。另一方面,随着用户业务的日益复杂,应用中对数据的查询通常包含了多个向量数据和非向量数据。例如,在为用户进行内容推荐时,通常需要结合用户个人的兴趣特征、用户的社交关系以及当前的热门话题进行综合性的分析和选择。此类查询通常需要结合多种数据查询方法,甚至通过多个数据处理系统交互完成,如何高效灵活地支持此类查询也是一个具有重要研究价值的问题。