Elasticsearch 中的向量搜索:设计背后的基本原理

news2024/11/15 17:44:49

作者:ADRIEN GRAND

实现向量数据库有不同的方法,它们有不同的权衡。 在本博客中,你将详细了解如何将向量搜索集成到 Elastisearch 中以及我们所做的权衡。

你有兴趣了解 Elasticsearch 用于向量搜索的特性以及设计是什么样子吗? 一如既往,设计决策有利有弊。 本博客旨在详细介绍我们如何选择在 Elasticsearch 中构建向量搜索。

向量搜索通过 Apache Lucene 集成到 Elasticsearch 中

首先是有关 Lucene 的一些背景知识:Lucene 将数据组织成定期合并的不可变段。 添加更多文档需要添加更多段。 修改现有文档需要自动添加更多段并将这些文档的先前版本标记为已删除。 段内的每个文档都由文档 ID 标识,文档 ID 是该文档在段内的索引,类似于数组的索引。 这种方法的动机是管理倒排索引,倒排索引不擅长就地修改,但可以有效地合并。

除了倒排索引之外,Lucene 还支持存储字段(文档存储)、文档值(列式存储)、术语向量(每个文档的倒排索引)以及段中的多维点。 向量已以相同的方式集成:

  • 新向量在索引时缓冲到内存中。
  • 当超出索引时间缓冲区的大小或必须使更改可见时,这些内存中的缓冲区将被序列化为段的一部分。
  • 分段会在后台定期合并在一起,以控制分段总数并限制每个分段的整体搜索时间开销。 由于它们是段的一部分,因此向量也需要合并。
  • 搜索必须组合索引中所有段的顶部向量命中(top vector hits)。
  • 对向量的搜索必须查看实时文档集,以便排除 token 为已删除的文档。

上面的系统是由 Lucene 的工作方式驱动的。

Lucene 目前使用分层可导航小世界 (Hierachical Navigable Small World - HNSW) 算法来索引向量。 在较高层次上,HNSW 将向量组织成一个图表(graph),其中相似的向量可能会连接起来。 HNSW 是向量搜索的热门选择,因为它相当简单,在向量搜索算法的比较基准上表现良好,并且支持增量插入。 Lucene 对 HNSW 的实现遵循 Lucene 将数据保留在磁盘上并依靠页面缓存来加速对频繁访问的数据的访问的准则。

近似向量搜索通过 knn 部分在 Elasticsearch 的 _search API 中公开。 使用此功能将直接利用 Lucene 的向量搜索功能。 向量还集成在 Elasticsearch 的脚本 API 中,允许执行精确的强力搜索(exact brute force search),或利用向量进行重新评分。

现在让我们深入探讨通过 Apache Lucene 集成向量搜索的优缺点。

缺点

利用 Apache Lucene 进行向量搜索的主要缺点是 Lucene 将向量与段联系起来。 然而,正如我们稍后将在 “优点” 部分中看到的,将向量与段联系起来也是实现高效预过滤、高效混合搜索和可见性一致性等主要功能的原因。

合并需要重新计算 HNSW 图

段合并需要采用 N 个输入段(默认合并策略通常为 10 个),并将它们合并为单个段。 Lucene 当前从没有删除的最大输入段创建 HNSW 图的副本,然后将来自其他段的向量添加到此 HNSW 图。 与在索引的生命周期内就地改变单个 HNSW 图相比,这种方法会产生索引时间开销,因为段是合并的。

搜索需要合并多个细分的结果

由于索引由多个段组成,因此搜索需要计算每个段上的 top-k 向量,然后将这些每个段的 top-k 命中合并为全局 top-k 命中。 通过并行搜索段可以减轻对延迟的影响,但与搜索单个 HNSW 图相比,这种方法仍然会产生一些开销。

RAM 需要随着数据集的大小进行扩展以保持最佳性能

遍历 HNSW 图会产生大量随机访问。 为了高效执行,数据集应适合页面缓存,这需要根据所管理的向量数据集的大小调整 RAM 的大小。 除了 HNSW 之外,还存在其他用于向量搜索的算法,它们具有更适合磁盘的访问模式,但它们也有其他缺点,例如更高的查询延迟或更差的召回率。

优点

数据集可以扩展到超出 RAM 总大小

由于数据存储在磁盘上,Elasticsearch 将允许数据集大于本地主机上可用的 RAM 总量,并且随着页面缓存中可容纳的 HNSW 数据比例的降低,性能将会下降。 如上一节所述,注重性能的用户需要根据数据集的大小来调整 RAM 大小,以保持最佳性能。

无锁搜索

就地更新数据结构的系统通常需要加锁,以保证并发索引和搜索下的线程安全。 Lucene 基于段的索引从不需要在搜索时锁定,即使在并发索引的情况下也是如此。 相反,索引所组成的段集会定期以原子方式更新。

支持增量更改

可以随时添加、删除或更新新向量。 其他一些近似最近邻搜索算法需要提供整个向量数据集。 然后,一旦提供了所有向量,就执行索引训练步骤。 对于这些其他算法,对向量数据集的任何重大更新都需要再次完成训练步骤,这可能会导致计算成本高昂。

与其他数据结构的可见性一致性

在如此低的级别集成到 Lucene 的一个好处是,在查看索引的时间点视图时,我们可以与其他开箱即用的数据结构保持一致。 如果你执行文档更新以更新其向量和某些其他关键字字段,则并发搜索保证会看到向量字段的旧值和关键字字段的旧值 - 如果时间点 视图是在更新之前创建的,或者是向量场的新值和关键字字段的新值(如果时间点视图是在更新之后创建的)。 同样,对于删除,如果文档被标记为已删除,那么包括向量存储在内的所有数据结构都将忽略它,或者如果它们对删除之前创建的时间点视图进行操作,则它们将看到它。

增量快照

向量是段的一部分,这一事实有助于快照通过利用两个后续快照通常共享其大部分段(尤其是较大的段)的事实来保持增量。 使用就地更改的单个 HNSW 图不可能实现增量快照。

过滤和混合支持

直接集成到 Lucene 中还可以与其他 Lucene 功能高效集成,例如使用任意 Lucene 过滤器预过滤向量搜索或将来自向量查询的命中与来自传统全文查询的命中组合起来。

通过拥有自己的与段关联的 HNSW 图,并且其中节点由文档 ID 索引,Lucene 可以就如何最好地预过滤向量搜索做出有趣的决定:要么通过线性扫描与过滤器匹配的文档(如果有选择性), 或者通过遍历图并仅考虑与过滤器匹配的节点作为 top-k 向量的候选节点。

与其他功能的兼容性

由于向量存储与任何其他 Lucene 数据结构一样,因此许多功能与向量和向量搜索自动兼容,包括:

  • 聚合
  • 文档级安全性
  • 字段级安全
  • 索引排序
  • 通过脚本访问向量(例如,从 script_score 查询或重新排序)

展望未来:索引和搜索分离

正如另一篇博客中所讨论的,Elasticsearch 的未来版本将在不同的实例上运行索引和搜索工作负载。 该实现本质上看起来就像你不断在索引节点上创建快照并在搜索节点上恢复它们。 这将有助于防止向量索引的高成本影响搜索。 使用单个共享 HNSW 图而不是多个段来实现索引和搜索的这种分离是不可能的,除非每次需要在新搜索中反映更改时通过网络发送完整的 HNSW 图。

结论

总的来说,Elasticsearch 提供了出色的向量搜索功能,并与其他 Elasticsearch 功能集成:

  • 向量搜索可以通过任何支持的过滤器进行预过滤,包括最复杂的过滤器。
  • 向量命中可以与任意查询的命中相结合。
  • 向量搜索与聚合、文档级安全性、字段级安全性、索引排序等兼容。
  • 包含向量的索引仍然遵循与其他索引相同的语义,包括 _refresh、_flush 和 _snapshot API。 它们还将支持无状态 Elasticsearch 中索引和搜索的分离。

这是以一些索引时间和搜索时间开销为代价完成的。 也就是说,向量搜索通常仍然以数十或数百毫秒的数量级运行,并且比强力精确搜索快得多。 更一般地说,与现有比较基准*中的其他向量存储相比,索引时间和搜索时间开销似乎都是可控的(查找 “luceneknn” 行)。 我们还相信,通过将向量搜索与其他功能相结合,可以释放向量搜索的许多价值。 此外,我们建议你查看 KNN 搜索调整指南,其中列出了许多有助于减轻上述缺点的负面影响的措施。

我希望你喜欢这个博客。 如果你有疑问,请随时通过讨论与我们联系。 你可以随意在现有部署中尝试向量搜索,或者在 Elastic Cloud 上免费试用 Elasticsearch Service(始终具有最新版本的 Elasticsearch)。

*在撰写本文时,这些基准测试尚未利用向量化。 有关向量化的更多信息,请阅读此博客。

本文中描述的任何特性或功能的发布和时间安排均由 Elastic 自行决定。 当前不可用的任何特性或功能可能无法按时交付或根本无法交付。

原文:Vector search in Elasticsearch: The rationale behind the design — Elastic Search Labs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/973304.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ROS】例说mapserver静态地图参数(对照Rviz、Gazebo环境)

文章目录 例说mapserver静态地图参数1. Rviz中显示的地图2. mapserver保存地图详解3. 补充实验 例说mapserver静态地图参数 1. Rviz中显示的地图 在建图过程中,rviz会显示建图的实时情况,其输出来自于SLAM,浅蓝色区域为地图大小&#xff0c…

SAP GUI登陆界面图片更换

导语:SAP登陆界面的图片不太好看,换一个客户需要的图片上去。 一、上传至SMW0 将准备好的图片,通过事物码SMW0进行上传。 二、更改配置表 事物码SM30,更改配置表【SSM_CUST】,以调用上传的图片 三、效果展示 作者…

Redis6搭建高可用的多主多从集群

Redis6搭建高可用的多主多从集群 环境准备搭建redis6集群安装redis6修改配置文件修改cluster-enabled修改cluster-config-file修改cluster-node-timeout 启动集群 环境准备 首先我们需要6台redis,那么为啥是6太呢?是因为我们要部署多master和多slaver集…

SpringCloudAlibaba之Sentinel介绍

文章目录 1 Sentinel1.1 Sentinel简介1.2 核心概念1.2.1 资源1.2.2 规则 1.3 入门Demo1.3.1 引入依赖1.3.2 集成Spring1.3.3 Spring中资源规则 1.4 Sentinel控制台1.5 核心原理1.5.1 NodeSelectorSlot1.5.2 ClusterBuilderSlot1.5.3 LogSlot1.5.4 StatisticSlot1.5.5 Authority…

ESP-C3入门23. I2C读写外部存储器

ESP-C3入门23. I2C读写外部存储器 一、准备工作1. 开发环境2. ESP32-C3 I2C资源介绍 二、主要函数1. 配置驱动程序2. 源时钟配置3. 安装驱动程序4. 通信5. 指示写入或读取数据 二、实现步骤1. 配置 I2C 总线:2. 初始化 I2C 总线:3. 与外部存储设备通信&a…

华为OD机试 - 找出经过特定点的路径长度 - 深度优先搜索(Java 2022 Q4 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…

特征值,特征向量,SVD分解,PCD分解

特征值,特征向量: 对于n阶方阵A,在A张成的空间里,存在非零向量v, 该向量转换到A张成的空间时,方向不变,大小变为λ倍。 ① Av λv 变换一下: ② (A - λI)v 0 对于A向量&#x…

安全编程:初始化那些你忽略掉的东西

对于黑客来说,特权提升漏洞是令他感到非常兴奋的事情,而有时候这种漏洞的来源仅仅是因为开发者忘记将内存缓冲区中的垃圾数据进行初始化。此话怎讲? 我想,现在每个人都应该熟悉 SecureZeroMemory 函数的使用,它用来擦…

ESD实时监控监测系统包括哪些功能

ESD实时监控监测系统是一种用于监测和控制静电放电的系统。静电放电(Electrostatic Discharge,ESD)是指由于电荷的不平衡而引起的突发放电现象,可能对电子元器件、设备和工作环境造成损害。 ESD实时监控监测系统通常包括以下功能…

elmentui表单重置及出现的问题

一、表单: 二、代码——拿官方的代码举例(做了一些小改动): 改动:model绑定的字段,由form改为queryParams ref绑定的字段form改为queryFrom 注:model绑定的这个字段用来做数据双向绑定的 注:ref绑定的这…

【TypeScript】一直提示 :无法重新声明块范围变量

【TypeScript】一直提示 :无法重新声明块范围变量 问题描述:在VSCode中编写ts代码时,编写保存完之后,通过tsc 文件名.ts编译就会看到变量名下面出现了红色的波浪线,提示的内容是无法重新声明块范围变量。 解决方法&am…

书单制作方法详细步骤,需要的小伙伴快来看看~

随着网络的发展,视频已经成为了人们获取信息的主要途径之一。书单视频作为一种特殊类型的视频,既能为观众提供阅读建议,又能为制作者带来收益,因此备受欢迎。本文将分享书单视频制作的详细步骤,帮助有兴趣的朋友们快速…

k8s基本概念

一、什么是Kubernetes二:Kubernetes部署方式的演变三、为什么要用K8S四、K8S的特性五、Kubernetes 集群架构与组件5.1 Master 组件① Kube-apiserver② Kube-controller-manager③ Kube-scheduler④ AUTH 认证模块 5.2 配置存储中心5.3 Node 组件① Kubelet② Kube-…

【校招VIP】产品分析之活动策划宣传

考点介绍: 产品的上线运营是非常重要的。应该来说好的产品都是运营出来的,在一运营过程中难免会依靠策划活动来提高产品知名度、用户数。用户粘度等等指标一,如何策划一个成功的活动就显得非常重要。 产品分析之活动策划宣传-相关题目及解析…

常见的几种排序算法

目录 一、插入排序 1、直接插入排序 1.1、排序方法 1.2、图解分析 1.3、代码实现 2、希尔排序 2.1、排序方法 2.2、图解分析 2.3、代码实现 二、选择排序 1、直接选择排序 1.1、排序方法 1.2、图解分析 1.3、代码实现 2、堆排序 2.1、排序方法 2.2、图解分析 …

Qt/C++音视频开发49-推流到各种流媒体服务程序

一、前言 最近将推流程序完善了很多功能,尤其是增加了对多种流媒体服务程序的支持,目前支持mediamtx、LiveQing、EasyDarwin、nginx-rtmp、ZLMediaKit、srs、ABLMediaServer等,其中经过大量的对比测试,个人比较建议使用mediamtx和…

QT DAY6

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);socket new QTcpSocket(this);//如果连接服务器成功,该客户端就会发射一个connected的信号。//我们…

【TypeScript学习】—基本类型(二)

【TypeScript学习】—基本类型(二) 一、TypeScript基本类型 //也可以直接用字面量进行类型声明let a:10; a10;//也可以使用 |来连接多个类型(联合类型)let b:"male"|"female"; b"male"; b"fe…

【Java】Java新特性--Records记录类型

Java 14引入了一个新的语言特性,即Records。Records是一种新的数据类,旨在简化Java中的数据类创建过程。它们提供了一种简洁的方式来创建具有默认的getter、setter、equals、hashCode和toString方法的不可变数据类。 以下是Records的基本语法&#xff1…

一文讲透:erp系统是什么?

erp系统是什么?这个看似简单的问题还真不好解答。因为现在99%的人都把ERP“系统”和ERP“软件”混淆了! ERP原本主要是专注于制造业的信息化问题,我把它叫真正的ERP“系统”。 但现在基本上只要是一个软件系统都可以叫ERP系统,什…