作者:来自 Elastic Tyler Perkins, Shani Sagiv, Gilad Gal, Ninoslav Miskovic
Elastic® Stack 8.12 构建于 Apache Lucene 9.9(有史以来最快的 Lucene 版本)之上,基于我们对标量量化和搜索并发性的贡献,为文本、向量和混合搜索带来了巨大进步。 此版本还优化了 Elasticsearch® 中的查询并行化以及 Kibana® 的增强功能,包括仪表板中的 ES|QL 查询编辑。
这些新功能使客户能够:
- 利用标量量化和融合乘加 (FMA),可降低成本和查询延迟并增强矢量数据搜索的摄取性能
- 使用查询并行化体验显着更快的搜索和聚合
- 直接在仪表板上编辑 ES|QL 查询,无需在仪表板和 Discover 应用程序之间切换,并利用对 ES|QL 应用内文档的改进来帮助用户更快地学习
Elastic Stack 8.12 现已在 Elastic Cloud 上推出,这是唯一包含最新版本中所有新功能的托管 Elasticsearch 产品。 你还可以下载 Elastic Stack 和我们的云编排产品 Elastic Cloud Enterprise 和 Elastic Cloud for Kubernetes,以获得自我管理的体验。
Elastic 8.12 中还有哪些新功能? 查看 8.12 公告帖子了解更多>>
更快、更高效的向量搜索,基于 Apache Lucene 9.9
在 Lucene 9.6 和 Lucene 9.9 之间,某些参数的速度提高了 7% 到 290%! 我们很高兴与你分享我们为 Lucene 所做的一些工作。
向量的标量量化 (scalar quantization)
执行向量搜索是基于比较查询向量与索引中向量的相似度,这意味着对向量的每个维度执行操作。 这意味着索引大小(影响成本)、摄取性能和查询延迟都是各个向量大小的函数。
许多用于生成向量的 ML 模型都输出具有 float32 元素的向量。 float32 消耗 4 个字节的内存,这允许很多值 (2^32)。 在大多数情况下,每个维度维护如此多的信息对相关性排名的好处非常有限,因为可以通过更小的维度元素获得相同的排序(排名)。 测试很简单:将维度值转换为更小的数据类型,然后看看排名变化了多少。 我们(和其他人)已经做到了这一点,并发现,通过稍微增加正在评估的候选者数量,当从 float32 转换为 int8(从 4 字节到 1 字节)时,很容易实现排名质量的零降低。
因此,我们在 Elasticsearch 中开发了对 int8 元素向量的支持,但到目前为止,从 float32 到 int8 的转换都是由用户执行的。 在 8.12 中,Elasticsearch 通过为向量添加新的索引选项类型来处理从 float32 到 int8 的线性转换:“int8_hnsw”。 其影响是降低成本、提高摄取性能和减少查询延迟,即使不增加正在评估的候选者数量,通常也不会对排名质量产生任何明显影响。 大多数向量搜索用户都会受益于这个选项。 有关更多信息,请参阅我们的 Lucene 中的标量量化简介和标量量化 101 博客。
kNN 向量搜索作为查询
使用 HNSW 算法的密集向量搜索现在可用作查询。 到目前为止,它必须是搜索请求中的顶级元素。 这是更大变化的一部分,旨在简化向量搜索的语法,并允许将向量搜索与其他搜索机制结合起来,以灵活地解决更复杂的用户请求。
在摄取时保存范数(norm)以获得更有效的余弦相似度
在 Elasticsearch中,我们支持四种向量相似度方法(欧几里得、曼哈顿、余弦和点积),但在实践中,大多数模型输出的向量应该通过余弦相似度进行比较。 我们一直建议用户使用点积而不是余弦,但为了做到这一点,用户必须对 ML 模型在推理时生成的向量进行归一化(即,将它们除以范数,使其长度变为 1)。 当向量被归一化时,它们按照归一化查询向量的点积的排序顺序将与它们在归一化之前按照余弦的排序顺序相同。 我们建议使用点积的原因是它在查询时需要更少的操作,从而允许更好的查询延迟。 如果你检查点积和余弦的运算,一切都会变得清晰:
换句话说,计算点积需要多次乘法运算和多次加法运算,其数量等于向量中的维数,而对于余弦,你首先执行点积,然后在此基础上执行两倍的点积。 计算点积所需的操作(加上一些小的开销),以便计算分母。 现在请记住,这是根据被视为潜在结果的每个向量计算的。 附带说明一下,大量乘法和求和运算是 8.12 中引入的 FMA 增强功能(见下文)如此重要的原因。
然而,你可能已经注意到分母,范数......
…实际上每个向量都是恒定的,因此我们不是在每次查询时重复计算它,而是在摄取时计算一次并保留归一化向量和范数(每个向量增加的开销可以忽略不计)。 这意味着使用余弦时的查询延迟与使用点积时一样高效,因为我们只是对归一化向量执行点积。 我们保留范数,以便我们可以根据需要计算原始向量,以供脚本访问。 最重要的是,不需要对向量进行归一化,这使得使用向量相似度变得更容易。
对于从 8.12 开始创建的任何索引,查询延迟都会自动得到改善。
用于向量搜索的 FMA 指令
向量比较(例如,通过点积或余弦运算)涉及重复将两个数字相乘并将结果与第三个数字相加(这就是计算点积的方式)
其中 n 是维数,并且对每个评估的向量重复它,这是很多)。
在这些情况下,我们更改了 Lucene 向 CPU 提供的指令,以便如果 CPU 支持(ARM 和 x86 CPU 支持),则乘法和加法运算将作为单个 CPU 运算(融合乘加)执行。 此更改改进了向量索引性能以及点积和余弦相似度的查询延迟。 Lucene 级别的点积改进约为 5%,余弦相似度索引可以达到两位数的影响(Elasticsearch 中的影响较小,因为 Elasticsearch 执行了一些额外的操作,但这些操作不受影响)。
为了从中受益,你唯一需要做的就是升级到 8.12。 改善自然会发生。 有关此更改的更多信息,请参阅我们的向量相似性计算 FMA 风格的博客。
当我们做出在 Lucene 中开发向量相似性并使 Lucene 成为向量搜索的最佳基础设施的战略决策时,关键考虑因素之一是我们希望用户从这种不断优化和改进引擎的细致工程工作中受益, FMA 优化就是这种持续改进的完美例子。
地理搜索和聚合
ES|QL 中的地理查询
Elasticsearch 已开始引入一种新的查询语言,它具有许多超越简化语法的优点。 作为新语言工作的一部分,我们现在通过 ES|QL 引入对 geo_point 和 point 数据类型的支持。 此功能仍处于技术预览阶段,并允许基本功能 - 主要是对这些地理空间数据类型执行选择操作。 这是我们将继续扩展的基础,因为我们看到诸如 join 之类的功能在地理场景中可以通过 ES|QL 获得大量使用。 请尝试一下并提供你的反馈。
Geo_shape 运行时字段
现在可以为 geo_shape 创建运行时字段。 运行时字段是通过运行轻松的脚本在查询时计算的,也可以临时定义为查询的一部分。 能够为 geo_shapes 形成运行时字段开启了许多新的可能性,例如能够从一个坐标系投影到另一个坐标系。
查询并行化
直到最近,Elasticsearch 仍会使用每个分片一个线程来运行每个查询。 当你同时运行多个查询时,这种方法非常有效,但当查询负载低于集群资源可以处理的水平时,计算资源的利用率可能不是最佳的,并且有可能改善查询延迟。
在 8.10 中,我们为向量搜索添加了查询并行化,这在适当的条件下显着改善了查询延迟。 我们现在为大多数其他查询和聚合添加类似的并行化。 有一些例外,最值得注意的是术语聚合(因为增加术语聚合的并行化会对它们的准确性产生负面影响)。 对聚合的影响尤其显着,有时会将延迟减少到以前的一半以下。 如果有可用线程,新的并行化机制将为每个查询的每个段(segment)分配最多一个线程,并限制每个查询分配的最大线程数。 你可以在我们的公开夜间基准测试中见证结果。
随着最近添加的重新路由摄取处理器(在 8.11 中正式发布),Elasticsearch 中的摄取管道变得更加灵活。 重新路由允许你根据 data_stream.dataset 和 data_stream.namespace 字段或你指定的其他字段和条件将日志分离到适当的数据流中。 唯一的缺点是,这在开发或调试摄取管道时增加了神秘感 —— 在不重新路由的情况下,在摄取单个文档期间可以执行的摄取管道的最大数量为两个(指定管道或默认管道,以及最终的管道)。
Elasticsearch 长期以来一直能够模拟执行给定文档的管道,因此你可以快速尝试新的管道或管道更改,而无需实际存储任何数据。 现有的 simulate pipeline API 可用于测试管道并查看生成的文档是什么样子。 使用重新路由时,每个文档执行的管道数量是无限的,因为每个管道都可以重新路由到另一个管道。 我们需要一种新的方法来模拟覆盖整个管道链的执行。
新的模拟摄取 API 提供了此功能,模拟将数据摄取到索引中。 它针对请求正文中提供的一组文档执行该索引的默认和最终管道。
模拟例子:
POST /_ingest/_simulate
{"docs": [{"_index": "my-index","_id": "123","_source": {"foo": "bar"}},…]
}
如果管道包含重新路由处理器,它将遵循该重新路由处理器到新索引,同时执行该索引的管道(与非模拟摄取的方式相同)。 没有数据被索引到 Elasticsearch 中。 相反,将返回转换后的文档,以及已执行的管道列表以及如果不是模拟则文档将被索引的索引名称。
模拟示例响应:
{"docs": [{"doc": {"_id": "123","_index": "my-index","_version": -3,"_source": {"field1": "value1","field2": "value2","foo": "bar"},"executed_pipelines": ["my-pipeline","my-final-pipeline"]}},…
这与现有的 simulate pipeline API 不同,因为你为该 API 指定单个管道,并且它仅运行该管道。 模拟管道 API 对于开发单个管道更有用,而新的 simulate ingest API 对于对摄取到索引时应用的各种管道的交互进行故障排除更有用。
你还可以在请求正文中提供替代管道定义,以代替系统中已有的管道定义。 管道替换仅在此请求中使用,以显示文档的外观以及它们将遵循哪些管道。
simulate ingest API 是对 simulate pipeline API 的补充,让你可以跨多个索引测试多个管道的集成,这是以前在不实际索引数据的情况下不可能实现的。
出于同样的原因,我们还向 bulk API 添加了一个选项 (list_execulated_pipelines=true),以使其包含在响应中的每个文档上执行的管道列表。
更方便地访问远程搜索的状态
Kibana 8.12 是我们追求更好的大规模分布式搜索的又一步(当然是 CCS!)。 在 8.11 中,我们通过 Kibana 检查器中的新集群和分片选项卡添加了触手可及的跨集群搜索响应信息。 在 8.12 中,我们为 Inspector 添加了一些不错的新功能,并使其在更多情况下可用。
如果你有很多远程集群(我们有超过 170 个),现在可以更快、更轻松地找到具有特定状态的子集或特定集群的状态。 你现在可以按搜索状态进行过滤:
如果你只想显示与特定名称匹配的集群,只需在搜索框中输入远程集群名称的一部分,我们就会过滤远程集群列表。
你还可以按名称、状态或响应时间对列表进行排序,以便在需要时轻松找到最慢的远程集群。
所有这些更好地了解远程搜索的好方法现在也可以在 Kibana 的更多地方使用。 在 8.12 中,集群和分片检查器将与 Discover 和 Maps 链接,而不仅仅是仪表板。 除了像 8.11 中那样进行部分搜索之外,我们还将在搜索失败时提供指向它的链接。
Kibana 警报
维护窗口
安排单个或定期维护时段以减少警报噪音并抑制通知。 例如,如果你有计划的停机或事件,维护时段可以防止在此期间出现误报。 在此版本中,用户将能够根据时间创建和定义窗口并设置基于查询的警报。
例如:作为用户,我想抑制每个星期一早上 9:00 至 10:00 的警报,并且仅针对与此查询匹配的警报:App: “Billing” and cluster: “X123” and project: “Prod”
连接器改进
- PagerDuty 警报操作现在由两个新字段支持: links 和 custom_details。
- ServiceNow ITSM 警报操作允许用户在警报恢复时定义事件解决方案,以确保 Elastic 警报和 ServiceNow 事件之间的双向同步。
在仪表板中编辑 ES|QL 查询
我们引入了直接通过仪表板编辑 ES|QL 查询的功能。 此视图还允许用户在不同的图表建议中进行选择。 这是非常强大的,因为用户不需要返回 “Discover” 页面来编辑查询并重新创建图表 - 他们可以简单地在仪表板上调整查询!
在仪表板中编辑 ES|QL 查询
Elastic Stack 8.12 是一个重大版本。 标量量化、融合乘加 (FMA) 和其他 Lucene 9.9 增强功能可降低成本和查询延迟,同时提供更快的向量搜索性能。 引入 kNN 向量搜索作为查询可以带来更好的开发人员体验。 查询并行化的进步通过加速各种搜索和聚合功能来减少查询延迟。 对于 ES|QL 用户来说,仪表板中直接提供的新查询编辑功能可带来更简单的用户体验,无需离开即可实现无缝调整。 这些升级,再加上地理搜索、摄取管道模拟、远程搜索状态访问和连接器增强方面的改进,所有这些加起来使 Elastic Stack 8.12 值得快速升级!
试试看
请阅读发行说明中了解这些功能以及更多信息。
现有 Elastic Cloud 客户可以直接从 Elastic Cloud 控制台访问其中许多功能。 没有利用云上的 Elastic? 开始免费试用。
本文中描述的任何特性或功能的发布和时间安排均由 Elastic 自行决定。 当前不可用的任何特性或功能可能无法按时交付或根本无法交付。
原文:Elastic Stack 8.12: Enhanced vector search with improvements to ES|QL and more | Elastic Blog