作者:来自 Elastic Mayya Sharipova, Gilad Gal, Quinn Harper

在四个数据集上的基准测试表明,一个索引设置可以应用 bfloat16 向量 量化 、缓存预加载和并行合并,从而提高向量搜索吞吐量并降低存储开销。
我们推出了一个用于生产环境向量搜索的设置。新的 vectordb_document 索引模式将原始向量以 bfloat16 格式存储,使其磁盘占用减少一半,并将向量数据结构预加载到文件系统缓存中。它还允许 segment 合并以不受限制且并行的方式运行。在我们的基准测试中,使用 bbq_hnsw 时,在高召回率下 QPS 最高提升了 2 倍;使用 bbq_disk 时,将索引达到可搜索状态所需的时间缩短了约 20%,且无需进行任何调优。该功能目前已在 Stateful Elasticsearch 9.5 和 Elasticsearch Serverless 中提供。
Elasticsearch 支持广泛的使用场景,包括可观测性指标和日志,以及复杂的地理空间分析。然而,随着向量搜索逐渐成为现代架构的核心组件,对专门优化的需求也越来越大。要让以向量为主的工作负载达到峰值性能,通常需要在复杂的配置选项空间中进行调整。为了减少这种运维负担,我们希望通过一个设置提供具有明确倾向的高性能默认配置,从而简化生产环境中的性能调优。vectordb_document 索引模式 就是专门为实现最佳向量搜索工作负载而设计的。
如何设置 vectordb_document 模式
设置只需要一个配置项。创建索引时,在索引设置中定义以下内容:
markdown
`
1. PUT my-index
2. {
3. "settings" : {
4. "index" : {
5. "mode" : "vectordb_document"
6. }
7. }
8. }
`AI写代码
vectordb_document 模式适用于所有 Elasticsearch 订阅层级,包括 Basic。
大多数用于向量搜索的索引也支持其他操作,例如聚合或地理搜索。它们同样支持混合搜索。由于向量搜索通常是这些混合工作负载中计算量最大的部分,我们建议使用 vectordb_document 索引模式,为最密集的操作优先提供 性能优化 。采用 vectordb_document 模式的索引仍然具备很强的功能,支持默认标准模式中几乎所有可用的操作,同时针对向量搜索对资源的高需求进行了专门优化。
"_document" 后缀代表了我们的路线图。我们还在开发 "vectordb_columnar" 模式,作为优化向量搜索的另一种方式,适用于不同的数据和访问模式。
四个数据集上的 Elasticsearch 向量搜索基准测试
为了验证这些默认设置,我们针对各种数据集以及两种索引 类 型:bbq_hnsw 和 bbq_disk,进行了广泛的基准测试。所有基准测试均在 AWS 上的单节点 Elasticsearch 实例中运行,使用 c8gd.2xlarge 实例(Graviton 4、ARM64、本地 NVMe SSD),pod 限制为 8GB RAM(2GB heap)和 4 个 CPU,并使用单个 shard。
数据集:
| 数据集 | 向量数量 | 维度 | 使用场景 |
|---|---|---|---|
laion-img-emb-512-20M-cosine |
2000 万 | 512 | 纯向量搜索(低维) |
msmarco-v2-10M-jina-v5-1024 |
1000 万 | 1024 | 纯向量搜索(中维) |
dbpedia-openai-1M-3072-angular |
100 万 | 3072 | 纯向量搜索(高维) |
arxiv-for-fanns-large |
270 万 | 4096 | 过滤搜索 |
bbq_hnsw:使用 vectordb_document 的 HNSW 索引性能
查询吞吐量和召回率
在全部四个数据集上,vectordb_document 都产生了更好的 QPS--召回率曲线,而优势的变化形态本身也很有参考价值。在 dbpedia-openai-1M、msmarco-v2-10M 和 arxiv-for-fanns-large 上,两条曲线在低召回率时开始时非常接近(在 arXiv 上基本完全相同),随着召回率提高逐渐拉开差距,在高召回率端分别达到约 1.4 倍、2.2 倍和 2 倍。在 laion-img-emb-512-20M 上,两条曲线从一开始就存在差距,并且从召回率 0.80 开始稳定在约 2 倍。
随着召回率提高,差距会扩大,因为更高的召回率需要通过过采样来实现,而过采样正是 vectordb_document 能够节省开销的地方。两种效果会叠加。bfloat16 存储将重新评分候选向量时需要读取的字节数减少了一半。对于分层可导航小世界(HNSW)来说,更重要的是,过采样因子会应用于图搜索本身;每个 segment 都会搜索 k × oversample 个候选项,因此成本会随着过采样倍数和 segment 数量的增加而增加。不受限制的并行合并会留下更少、更大的图(14--21 个 segment,而不是 22--29 个),同时图文件和量化向量文件会预加载到文件系统缓存中,因此 vectordb_document 在每次增加过采样倍数时付出的代价要低得多。
比较完全相同的搜索设置,而不是相同的召回率,可以更清楚地体现这种效果。在关闭重新评分的情况下,两种模式的性能差距在 1%--28% 以内;当过采样为 5 时,vectordb_document 的速度快 2--4 倍;当过采样为 10 时,最高可以快 10 倍。这些高过采样设置位于 QPS--召回率前沿之外,这也是为什么上面的曲线最高只达到约 2 倍,但它们能够单独体现性能提升究竟来自哪里。
| 过采样 | DBpedia | LAION | MS MARCO | arXiv |
|---|---|---|---|---|
| 关闭 | 1.23× | 1.28× | 1.11× | 1.01× |
| 5 | 4.07× | 2.66× | 2.66× | 2.05× |
| 10 | 10.5× | 2.33× | 2.46× | 4.03× |




索引速度和合并行为
在我们的基准测试中,vectordb_document 使上传时间增加了约 16%。这是预期的结果:合并现在会以不受限制且并行化的方式跨线程运行,因此在文档仍在写入的同时,会与索引建立过程竞争 CPU。四个数据集测得的索引建立时间增加了 9%--26%。HNSW 图构建受 CPU 限制,因此这种竞争会直接体现出来。
相同的变化也使上传后的阶段成本大幅降低。禁用自动限流会完全移除合并速率限制(在默认模式下,DBpedia 有 57% 的合并时间处于限流状态),而 bfloat16 将原始向量数据减少一半,使需要合并的总字节数减少 42%--49%。在四个数据集中的三个数据集上,数据写入后的合并完成时间缩短了 75%--86%,使索引达到可搜索状态的总时间仅比基线高约 6%。DBpedia 是一个例外,其合并尾部占据了主要时间,因此总时间实际上下降了 25%。


bbq_disk:使用 vectordb_document 的基于磁盘的向量搜索性能
bbq_disk 查询吞吐量和召回率
对于 bbq_disk 索引,vectordb_document 模式对搜索吞吐量的影响因数据集而异。在低维数据集上,相同召回率下的 QPS 基本没有变化:laion-img-emb-512-20M-cosine(512 维)和 msmarco-v2-10M-jina-v5-1024(1024 维)在整个召回率范围内的表现非常接近,vectordb_document 在较低召回率端领先,而在高召回率端则落后几个百分点。在高维数据集上,我们在相同召回率下观察到了约 20% 的稳定提升:dbpedia-openai-1M-3072-angular(3072 维)和 arxiv-for-fanns-large(4096 维)。
我们的解释是,这主要来自重新评分的影响。vectordb_document 将向量以 bfloat16 格式存储,因此重新评分每个候选项时读取的字节数为 2 × dims,而不是 4 × dims。这一点也得到了扫描测试的直接支持:优势会随着查询时的过采样倍数增加而扩大,而过采样倍数正是决定需要重新评分多少候选项的因素。在 DBpedia 上,QPS 比值从过采样为 3 时的 1.16 倍上升到过采样为 8 时的 4.3 倍;在 arXiv 上则从 1.20 倍上升到 1.56 倍。相比之下,在 LAION 和 MS MARCO 上,该比值保持平稳,或者略微低于 1。对于规模较小但维度较高的数据集,重新评分在查询中的占比明显更大;而对于 1000 万和 2000 万向量的数据集,扫描 1-bit 倒排列表占据了主要开销。




索引速度和合并行为
在四个数据集上,vectordb_document 都将索引完全合并并达到可搜索状态所需的总时间缩短了约 20%。每个数据集都有所改善,从 msmarco-v2-10M 的 6% 到 dbpedia-openai-1M 的 50% 不等,其中 DBpedia 的上传后合并阶段单独就从 322 秒下降到 54 秒。单独来看,上传时间的结果并不那么明确:在下面图表所展示的当天测试中,根据数据集的不同,上传完成时间缩短了 2%--15%;但在更早的一组测试中,上传速度略有下降,因此我们将上传时间视为基本不变到略有提升,并将达到可搜索状态所需的时间视为真正的结果。
性能提升几乎全部来自合并。在默认模式下,Elasticsearch 会限制合并可以写入数据的速度,而这一限流机制产生了明显影响:DBpedia 75% 的合并时间以及 LAION 73% 的合并时间都消耗在因限流而暂停上。vectordb_document 禁用了这一限流机制,因此暂停时间变为零,DBpedia 的合并时间下降了 63%,LAION 下降了 42%。bfloat16 也会带来帮助,原因相同:限流机制按照写入的字节数进行限制,因此原始向量数据减少一半意味着在限额下需要写入的数据更少。不同数据集之间的提升幅度与限流程度而不是字节数量相关:arXiv 只有 21% 的合并时间受到限流,但合并时间减少了 30%;而 MS MARCO 从未受到限流,虽然写入字节数减少了 55%,合并时间却只减少了 11%。
两种索引类型在数据写入阶段的表现不同,因为它们的合并成本不同。合并 bbq_hnsw segment 意味着重新构建 HNSW 图:这是一项受 CPU 限制的工作,会直接与新写入文档时同样受 CPU 限制的图构建过程竞争。在只有 4 个 CPU 的 pod 上,这种竞争会表现为上传速度变慢。bbq_disk 的合并则主要受写入字节数影响,而不是 CPU,因此解除限流后会使用本地 NVMe 尚有余量的 I/O 带宽,同时 bfloat16 意味着本来就需要写入更少的字节。两种索引类型都能更快地达到完全合并的状态;区别仅在于上传阶段是否需要为此付出代价。


vectordb_document 在底层设置了什么
element_type(dense_vector)
-
值: bfloat16。
-
影响: 将原始向量的每个维度以 bfloat16 而不是默认的 float32 进行存储,使原始向量的存储空间减少一半,同时对召回率的影响可以忽略不计。
-
收益: 更小的磁盘占用(降低总体拥有成本 TCO),更快地获取用于重新评分的向量。
动态浮点数组映射
-
值: 包含 32 个或更多值的浮点数组会被动态映射为
dense_vector。(在默认模式下,该阈值为 128。) -
影响: 无需显式将字段声明为 dense vector 字段;系统会自动识别。
-
收益: 配置更加简单。
exclude_source_vectors
-
值: true。
-
影响: 向量只在向量索引中存储一次,不会在
_source中重复存储。它们不会出现在响应的_source中,但仍然可以按请求进行检索。 -
收益: 更小的磁盘占用;查询速度更快,因为大型向量不再随每次
_source获取一起传输。
index.store.preload
-
值: `"vex"`、`"veq"`、`"veb"`、`"cenivf"`。
-
影响: 每当新的 segment 打开时,将搜索时使用的向量数据结构预加载到文件系统缓存中。
-
收益: 降低查询延迟。
index.merge.intra_merge_parallelism_enabled
-
值: true。
-
影响: 使用并行线程进行 segment 合并,以获得最佳的 segment 大小。
-
收益: 更快地收敛到更少、更大的 segment,从而提高召回率并降低查询延迟。
index.merge.scheduler.auto_throttle
-
值: false。
-
影响: 允许合并以全速进行。
-
收益: 更快地达到最佳 segment 大小,从而提高召回率并降低查询延迟。
虽然这些默认设置针对大多数使用场景进行了优化,但其中大多数设置都可以单独覆盖,以适应独特的硬件限制或极端的性能需求,但有一个例外:exclude_source_vectors: true 在 vectordb_document 索引中是锁定的,无法更改。
总结
vectordb_document 索引模式为向量搜索提供了一个适用于生产环境的基础:通过采用高性能默认设置,团队可以专注于构建功能,而不必手动调整合并或存储设置,也不必调整预加载设置。
在四个数据集上,整体结果都持续向好,不过不同索引类型之间的平衡有所不同。对于 bbq_hnsw,所有数据集的 QPS--召回率都有所提升,从低召回率时大致持平,到高召回率端最高达到约 2 倍,代价是适度增加数据写入成本:上传时间延长约 16%,达到可搜索状态的索引总时间延长约 6%。对于 bbq_disk,情况正好相反:达到可搜索状态的索引总时间缩短了约 20%;在高维数据集(3072 和 4096 维)上,相同召回率下的搜索性能提升了约 20%,而在低维数据集上基本没有变化。两者的差异归根结底取决于合并的成本:重新构建 HNSW 图属于 CPU 密集型工作,会与索引建立过程竞争 CPU;而 bbq_disk 的合并受写入速度限制,解除限流后可以更快地运行。
在这两种情况下,新的默认设置都让系统朝着大多数用户希望的方向发展,无需针对每个索引进行调优。而对于那些真正取决于数据本身的设置,例如量化程度,现在自动校准功能会为你推导这些设置。(参见Elasticsearch 如何自动调优向量量化以达到你的召回率目标。)
你可以在 Stateful Elasticsearch 9.5 或 Serverless 中创建使用 vectordb_document 索引模式的索引来进行尝试。
原文:Vector quantization in Elasticsearch: auto parameter selection | Elasticsearch Labs