<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Ugo Sangiorgi - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Ugo Sangiorgi - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/cn/search-labs/author/ugo-sangiorgi</link>
    </image>
    <link>https://www.elastic.co/cn/search-labs/author/ugo-sangiorgi</link>
    <atom:link href="https://www.elastic.co/cn/search-labs/rss/author/ugo-sangiorgi.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[cn]]></language>
    <lastBuildDate>Sun, 13 Sep 2026 06:36:07 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Elasticsearch BBQ 与 OpenSearch FAISS：矢量搜索性能比较]]></title>
    <description><![CDATA[Elasticsearch BBQ 和 OpenSearch FAISS 的性能比较。]]></description>
    <content:encoded><![CDATA[<p><strong>二进制量化矢量搜索使用 BBQ 的 Elasticsearch 比使用 FAISS 的 OpenSearch 快 5 倍</strong>。Elastic 收到了来自社区的请求，希望澄清 Elasticsearch 和 OpenSearch 之间的性能差异，尤其是在语义搜索/矢量搜索领域，因此我们进行了这些性能测试，以提供清晰的、数据驱动的比较。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta8792b5284e7a553/6a1709b9961e69a084c4cee6/7f4f8d08f7bee188423e4e65f0caefc7e34f0355-1600x681.png" alt="Elasticsearch BBQ 与 OpenSearch FAISS - 速度&amp; 吞吐量 召回率比较" /><h2>二进制量化对决</h2><p>以原始形式存储高维向量会耗费大量内存。量化技术可将这些矢量压缩为紧凑的表示形式，从而大大减少内存占用。然后，搜索在压缩空间内进行，从而降低了计算复杂度，加快了搜索速度，尤其是在大型数据集中。</p><p>Elastic 致力于使 Lucene 成为性能一流的矢量引擎。在 Elasticsearch 8.16 中，我们在 Lucene 的基础上引入了<a href="https://www.elastic.co/cn/search-labs/blog/better-binary-quantization-lucene-elasticsearch">更好的二进制量化</a>(BBQ)，并在 8.18 和 9.0 中进一步发展。BBQ 基于一种新的<a href="https://www.elastic.co/cn/search-labs/blog/optimized-scalar-quantization-elasticsearch">标量量化</a>方法，将 float32 维度减少到比特，在保持高排名质量的同时，减少了 ~95% 内存。</p><p>另一方面，OpenSearch 使用多种矢量引擎：nmslib（现已废弃）、Lucene 和 FAISS。在<a href="https://www.elastic.co/cn/search-labs/blog/elasticsearch-opensearch-vector-search-performance-comparison"> 上</a> 一篇 博客 中，我们比较了 Elasticsearch 和 OpenSearch 的向量搜索。我们使用了三个不同的数据集，并在两种产品上测试了不同的引擎和配置组合。</p><p>本博客重点介绍这两种产品目前提供的二进制量化算法。我们使用 BBQ 对 Elasticsearch 进行了测试，并使用<a href="https://opensearch.org/docs/latest/search-plugins/knn/knn-vector-quantization/#binary-quantization">FAISS 的二进制量化</a>（<a href="https://github.com/elastic/rally-tracks/edit/master/openai_vector">openai_vector</a>Rally track）对 OpenSearch 进行了测试。</p><p>主要目的是评估两种解决方案在相同召回率下的性能。<em>召回</em>是什么意思？召回率是衡量搜索系统成功检索到多少相关结果的指标。</p><p>在这项评估中，<em>recall</em>@k 尤为重要，其中k代表所考虑的顶级结果的数量。因此，<strong>Recall@10</strong>、<strong>Recall@50 和 Recall@100</strong>分别用来衡量有多少真正相关的结果出现在检索结果的前 10、50 和 100 项中。召回率以 0 到 1 的范围表示（或 0% 到 100% 精确度）。这一点很重要，因为我们讨论的是近似 KNN (ANN)，而不是精确 KNN，后者的召回率总是 1 (100%).</p><p>对于每个<em>k</em>值，我们还指定了<em>n， </em>即在应用最终排名之前考虑的候选者数量。这意味着，对于 Recall@10、Recall@50 和 Recall@100，系统首先使用二进制量化算法检索<em>n 个</em>候选项，然后对它们进行排序，以确定前<em>k 个</em>结果是否包含预期的相关项。</p><p>通过控制<em>n</em>，我们可以分析效率和精度之间的权衡。较高的<em>n</em>通常会<strong>增加</strong>召回率，因为有更多候选者可供排序，但同时也会<strong>增加</strong>延迟和<strong> 降低 </strong>吞吐量。相反，<em>n</em>越小，检索速度越快，但如果初始集合中包含的相关候选信息太少，则可能会降低召回率。</p><p>在这次比较中，Elasticsearch 在相同的设置下比 OpenSearch 的延迟更低，吞吐量更高。</p><h2>方法</h2><p>完整的配置，以及 Terraform 脚本、Kubernetes 清单和特定的 Rally 轨道，都可在此<a href="https://github.com/elastic/elasticsearch-opensearch-vector-performance/tree/bbq">仓库</a> <a href="https://github.com/elastic/elasticsearch-opensearch-vector-performance/tree/bbq/rally-custom/custom_tracks/elasticsearch/openai_vector_bq"><em>openai_vector_bq</em></a> 下找到。</p><p>与之前的基准测试一样，我们使用的 Kubernetes 集群由以下部分组成：</p><ul><li><p>1 个用于 Elasticsearch 9.0 的节点池，包含 3 台<code>e2-standard-32</code> 机器（128GB 内存和 32 个 CPU）</p></li><li><p>1 个用于 OpenSearch 2.19 的节点池，包含 3 台<code>e2-standard-32</code> 机器（128GB 内存和 32 个 CPU）</p></li><li><p>1 个用于 Rally 的节点池，包含 2 台<code>e2-standard-4</code> 机器（16GB 内存和 4 个 CPU）</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt934e988e96a5849f/6a1709bbacf08838f9be9ac1/169bb6033f6eebfd1b177b3446bf916fde4ee5c5-1600x856.png" alt="Elasticsearch BBQ 与 Opensearch FAISS 方法论设置对比" /><p>我们建立了一个版本为 9.0 的 Elasticsearch 集群和一个版本为 2.19 的 OpenSearch 集群。</p><p>Elasticsearch 和 OpenSearch 都使用了完全相同的设置进行测试：我们使用了经过<a href="https://github.com/elastic/elasticsearch-opensearch-vector-performance/commit/b97d5d95c22c8cf862f2030964524bdd156a5da3"> 一些修改的</a><a href="https://github.com/elastic/rally-tracks/edit/master/openai_vector"> openai_vector</a> Rally track，它使用了来自<a href="https://huggingface.co/datasets/BeIR/nq"> NQ 数据集</a> 的 250 万份文档，并使用 OpenAI 的<a href="https://openai.com/blog/new-and-improved-embedding-model"> text-embedding-ada-002 模型</a> 生成了丰富的嵌入。</p>{
  "source-file": "open_ai_corpus-initial-indexing.json.bz2",
  "document-count": 2580961,
  "compressed-bytes": 32076749416,
  "uncompressed-bytes": 90263571686
}<p>结果报告了在不同召回级别（召回率@10、召回率@50 和召回率@100）下，使用 8 个客户端同时执行搜索操作所测出的延迟和吞吐量。我们只使用一个分片，没有副本。</p><p>我们运行了以下 k-n-rescore 组合，例如10-2000-2000，或<em>k:10</em>、<em>n:2000</em>和<em>rescore:2000</em>将检索 n 个候选者（2000）中的前 k（10），并对 2000 个结果进行重新评分（相当于 "超抽样因子 "1）。每次搜索运行 10.000 次，预热 1000 次：</p><p></p><p><u><strong>召回@10</strong></u></p><ul><li><p>10-40-40</p></li><li><p>10-50-50</p></li><li><p>10-100-100</p></li><li><p>10-200-200</p></li><li><p>10-500-500</p></li><li><p>10-750-750</p></li><li><p>10-1000-1000</p></li><li><p>10-1500-1500</p></li><li><p>10-2000-2000</p></li></ul><p><u><strong>回忆@50</strong></u></p><ul><li><p>50-150-150</p></li><li><p>50-200-200</p></li><li><p>50-250-250</p></li><li><p>50-500-500</p></li><li><p>50-750-750</p></li><li><p>50-1000-1000</p></li><li><p>50-1200-1200</p></li><li><p>50-1500-1500</p></li><li><p>50-2000-2000</p></li></ul><p><u><strong>Recall@100</strong></u></p><ul><li><p>100-200-200</p></li><li><p>100-250-250</p></li><li><p>100-300-300</p></li><li><p>100-500-500</p></li><li><p>100-750-750</p></li><li><p>100-1000-1000</p></li><li><p>100-1200-1200</p></li><li><p>100-1500-1500</p></li><li><p>100-2000-2000</p></li></ul><p>为了复制基准，Rally-elasticsearch 和 rally-opensearch 的 Kubernetes 清单都将所有相关变量外部化到了 ConfigMap 中，可<a href="https://github.com/elastic/elasticsearch-opensearch-vector-performance/blob/bbq/k8s/rally-openai_vector-es-bq.yml">在此处</a>（ES）和<a href="https://github.com/elastic/elasticsearch-opensearch-vector-performance/blob/bbq/k8s/rally-openai_vector-os-bq.yml">此处</a>（OS）查看。可以自定义<em>search_ops</em>参数，以测试 k、n 和 rescore 的任意组合。</p><h3>OpenSearch Rally 配置</h3><p><code>/k8s/rally-openai_vector-os-bq.yml</code></p>apiVersion: v1
kind: ConfigMap
metadata:
  name: rally-params-os
  labels:
    app: rally-opensearch
data:
  user-tags.json: |
    {
      "product": "OpenSearch",
      "product-version": "OpenSearch-2.19.0",
      "product-label": "OpenSearch-2.19-faiss",
      "benchmark-run": "19-feb-recall@100"
    }
  track-params.json: |
    {
      "mapping_type": "vectors-only-mapping-with-docid",
      "standalone_search_clients": 8,
      "standalone_search_iterations": 5000,
      "ann_threshold": 0,
      "vector_mode": "on_disk",
      "compression_level": "32x",
      "vector_method_name": "hnsw",
      "vector_method_engine": "faiss",
      "search_ops": [
        [100, 200, 200],
        [100, 250, 250],
        [100, 300, 300],
        [100, 500, 500],
        [100, 750, 750],
        [100, 1000, 1000],
        [100, 1200, 1200],
        [100, 1500, 1500],
        [100, 2000, 2000]
      ]
    }<h3>Opensearch 索引配置</h3><p>然后，ConfigMap 中的变量将用于索引配置，某些参数则保持不变。OpenSearch 中的 1 位量化是通过<a href="https://opensearch.org/docs/latest/search-plugins/knn/knn-vector-quantization/#binary-quantization"> 将压缩级别设置为 "32x " 来配置的</a> 。</p><p><code>index-vectors-only-mapping-with-docid-mapping.json</code></p>{
  "settings": {
    {% if preload_pagecache %}
    "index.store.preload": [
      "vec", "vex", "vem", "veq", "veqm", "veb", "vebm"
    ],
    {% endif %}
    "index.number_of_shards": {{ number_of_shards | default(1) }},
    "index.number_of_replicas": {{ number_of_replicas | default(0) }},
    "index.knn": true,
    "index.knn.advanced.approximate_threshold": {{ ann_threshold | default(15000) }}
  },
  "mappings": {
    "dynamic": false,
    "properties": {
      "docid": {
        "type": "keyword"
      },
      "emb": {
        "type": "knn_vector",
        "dimension": 1536,
        "space_type": "innerproduct",
        "data_type": "float",
        "mode": {{ vector_mode | default("in_memory") | tojson }},
        "compression_level": {{ compression_level | default("32x") | tojson }},
        "method": {
          "name": {{ vector_method_name | default("hnsw") | tojson }},
          "engine": {{ vector_method_engine | default("faiss") | tojson }},
          "parameters": {
            "ef_construction": 100,
            "m": 16
          }
        }
      }
    }
  }
}<h3>Elasticsearch Rally 配置</h3><p><code>/k8s/rally-openai_vector-es-bq.yml</code></p>apiVersion: v1
kind: ConfigMap
metadata:
  name: rally-params-es
  labels:
    app: rally-elasticsearch
data:
  user-tags.json: |
    {
      "product": "Elasticsearch",
      "product-version": "Elasticsearch-9.0.0-ade01164",
      "product-label": "Elasticsearch-9.0-BBQ",
      "benchmark-run": "19-feb-recall@100"
    }
  track-params.json: |
    {
      "mapping_type": "vectors-only-mapping-with-docid",
      "standalone_search_clients": 8,
      "standalone_search_iterations": 5000,
      "vector_index_type": "bbq_hnsw",
      "search_ops": [
        [100, 200, 200],
        [100, 250, 250],
        [100, 300, 300],
        [100, 500, 500],
        [100, 750, 750],
        [100, 1000, 1000],
        [100, 1200, 1200],
        [100, 1500, 1500],
        [100, 2000, 2000]
      ]
    }<h3>Elasticsearch 索引配置</h3><p><code>index-vectors-only-mapping-with-docid-mapping.json</code></p>{
  "settings": {
    {# non-serverless-index-settings-marker-start #}
    {%- if build_flavor != "serverless" or serverless_operator == true -%}
    {% if preload_pagecache %}
    "index.store.preload": [ "vec", "vex", "vem", "veq", "veqm", "veb", "vebm" ],
    {% endif %}
    "index.number_of_shards": {{ number_of_shards | default(1) }},
    "index.number_of_replicas": {{ number_of_replicas | default(0) }}
    {%- endif -%}
    {# non-serverless-index-settings-marker-end #}
  },
  "mappings": {
    "dynamic": false,
    "properties": {
      "docid": {
        "type": "keyword"
      },
      "emb": {
        "type": "dense_vector",
        "element_type": "float",
        "dims": 1536,
        "index": true,
        "similarity": "dot_product",
        "index_options": {
          "type": {{ vector_index_type | default("bbq_hnsw") | tojson }},
          "ef_construction": 100,
          "m": 16
        }
      }
    }
  }
}<h2>实施结果</h2><p>对结果有多种解释方法。对于延迟和吞吐量，我们绘制了每个召回级别的简化图和详细图。如果我们考虑到每项指标 "越高越好"，就很容易发现其中的差异。不过，延迟是负值（实际上越低越好），而吞吐量是正值。在简化图表中，我们使用<strong>（召回率/延迟）*10000 </strong>（简称 "速度"）和<strong> 召回率*吞吐量</strong>，因此这两个指标都意味着速度越快和吞吐量越大越好。让我们开始吧。</p><h3>召回 @ 10 - 简化</h3><p>在这种召回水平下，Elasticsearch BBQ 比 OpenSearch FAISS<strong>快 5 倍 </strong>（平均快 3.9 倍），<strong>吞吐量</strong>平均高出 3.2 倍。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3de6b3460127a8ae/6a1709bcb339d55975769f6f/d580ad53e8974bd3aa75957c413a0136c4e465c5-1600x681.png" alt="在速度和吞吐量方面，Elasticsearch BBQ 比 OpenSearch FAISS 快达 5 倍（平均快 3.9 倍），吞吐量平均高出 3.2 倍 Recall@10" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd47045013cac5e9d/6a1709be0e2e49599a41a088/18edce667fe36ab95033264ef8df6f352dda2425-2044x866.png" alt="与 OpenSearch FAISS 相比，Elasticsearch BBQ 的速度快达 5 倍（平均快 3.9 倍），吞吐量平均高出 3.2 倍。" /><h4>召回 @ 10 - 详细</h4><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0ecb02d4a2967dbd/6a1709bf14b270c04fe3c5c6/a7459b87e679f4ad963d0e2f1685499b40f6f050-1600x799.png" alt="Elasticsearch BBQ 与 Opensearch FAISS 的详细召回@10 延迟比较" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt182da309ad6cfd39/6a1709c166c4f99077f8bfd8/c6036f55a13377654d296eb3148c7199e1965475-1600x799.png" alt="Elasticsearch BBQ 与 Opensearch FAISS 的详细召回率@10 吞吐量比较。" /><p></p><p>工作</p><p>latency.mean</p><p>吞吐量平均值</p><p>平均调用次数</p><p>Elasticsearch-9.0-BBQ</p><p>10-100-100</p><p>11.70</p><p>513.58</p><p>0.89</p><p>Elasticsearch-9.0-BBQ</p><p>10-1000-100</p><p>27.33</p><p>250.55</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>10-1500-1500</p><p>35.93</p><p>197.26</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>10-200-200</p><p>13.33</p><p>456.16</p><p>0.92</p><p>Elasticsearch-9.0-BBQ</p><p>10-2000-2000</p><p>44.27</p><p>161.40</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>10-40-40</p><p>10.97</p><p>539.94</p><p>0.84</p><p>Elasticsearch-9.0-BBQ</p><p>10-50-50</p><p>11.00</p><p>535.73</p><p>0.85</p><p>Elasticsearch-9.0-BBQ</p><p>10-500-500</p><p>19.52</p><p>341.45</p><p>0.93</p><p>Elasticsearch-9.0-BBQ</p><p>10-750-750</p><p>22.94</p><p>295.19</p><p>0.94</p><p>OpenSearch-2.19-faiss</p><p>10-100-100</p><p>35.59</p><p>200.61</p><p>0.94</p><p>OpenSearch-2.19-faiss</p><p>10-1000-1000</p><p>156.81</p><p>58.30</p><p>0.96</p><p>OpenSearch-2.19-faiss</p><p>10-1500-1500</p><p>181.79</p><p>42.97</p><p>0.96</p><p>OpenSearch-2.19-faiss</p><p>10-200-200</p><p>47.91</p><p>155.16</p><p>0.95</p><p>OpenSearch-2.19-faiss</p><p>10-2000-2000</p><p>232.14</p><p>31.84</p><p>0.96</p><p>OpenSearch-2.19-faiss</p><p>10-40-40</p><p>27.55</p><p>249.25</p><p>0.92</p><p>OpenSearch-2.19-faiss</p><p>10-50-50</p><p>28.78</p><p>245.14</p><p>0.92</p><p>OpenSearch-2.19-faiss</p><p>10-500-500</p><p>79.44</p><p>97.06</p><p>0.96</p><p>OpenSearch-2.19-faiss</p><p>10-750-750</p><p>104.19</p><p>75.49</p><p>0.96</p><h3>召回 @ 50 - 简化</h3><p>在这种召回水平下，Elasticsearch BBQ 比 OpenSearch FAISS<strong> 快多达 5 倍</strong> （平均快<strong> 4.2 倍），平均 吞吐量多</strong> 3.9 倍 。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt486683f2c7a1d677/6a1709c2a6c2b995bde796a3/3189ffb330948b35854eeea9ae317d4846c14972-1600x681.png" alt="Recal @50 向量性能对比 Elasticsearch BBQ vs Opensearch FAISS" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltba830c6741784682/6a1709c4a292990627d00ff7/607383d674dcf0b8f94bfb1a450063f52fcbeb15-2060x876.png" alt="Elasticsearch BBQ 的速度比 OpenSearch FAISS 快 5 倍（平均快 4.2 倍），吞吐量平均高出 3.9 倍。" /><h4>详细结果 - 召回率 @ 50</h4><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt821775e7f87e5ede/6a1709c6a6c2b90af3e796a7/ebfffe0b776aad31dd03d315cfbf5aa098b41226-1600x789.png" alt="Recall@50 Elasticsearch BBQ 和 Opensearch FAISS 延迟结果" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4f47784ed1017c15/6a1709c7e8fbce0fbe39fbf5/ae20cf870a65c400a2112bbad62eb56e244f549a-1600x799.png" alt="Recall@50 Elasticsearch BBQ 和 Opensearch FAISS 吞吐量结果" /><p></p><p>任务</p><p>平均时延</p><p>吞吐量平均值</p><p>平均召回率</p><p>Elasticsearch-9.0-BBQ</p><p>50-1000-1000</p><p>25.71</p><p>246.44</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>50-1200-1200</p><p>28.81</p><p>227.85</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>50-150-150</p><p>13.43</p><p>362.90</p><p>0.90</p><p>Elasticsearch-9.0-BBQ</p><p>50-1500-1500</p><p>33.38</p><p>202.37</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>50-200-200</p><p>12.99</p><p>406.30</p><p>0.91</p><p>Elasticsearch-9.0-BBQ</p><p>50-2000-2000</p><p>42.63</p><p>163.68</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>50-250-250</p><p>14.41</p><p>373.21</p><p>0.92</p><p>Elasticsearch-9.0-BBQ</p><p>50-500-500</p><p>17.15</p><p>341.04</p><p>0.93</p><p>Elasticsearch-9.0-BBQ</p><p>50-750-750</p><p>31.25</p><p>248.60</p><p>0.94</p><p>OpenSearch-2.19-faiss</p><p>50-1000-1000</p><p>125.35</p><p>62.53</p><p>0.96</p><p>OpenSearch-2.19-faiss</p><p>50-1200-1200</p><p>143.87</p><p>54.75</p><p>0.96</p><p>OpenSearch-2.19-faiss</p><p>50-150-150</p><p>43.64</p><p>130.01</p><p>0.89</p><p>OpenSearch-2.19-faiss</p><p>50-1500-1500</p><p>169.45</p><p>46.35</p><p>0.96</p><p>OpenSearch-2.19-faiss</p><p>50-200-200</p><p>48.05</p><p>156.07</p><p>0.91</p><p>OpenSearch-2.19-faiss</p><p>50-2000-2000</p><p>216.73</p><p>36.38</p><p>0.96</p><p>OpenSearch-2.19-faiss</p><p>50-250-250</p><p>53.52</p><p>142.44</p><p>0.93</p><p>OpenSearch-2.19-faiss</p><p>50-500-500</p><p>78.98</p><p>97.82</p><p>0.95</p><p>OpenSearch-2.19-faiss</p><p>50-750-750</p><p>103.20</p><p>75.86</p><p>0.96</p><h3>召回 @ 100</h3><p>在这种召回水平下，Elasticsearch BBQ 比 OpenSearch FAISS<strong>快 5 倍 </strong>（平均快 4.6 倍），<strong>吞吐量 </strong>平均高 3.9 倍。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt380eb9165343a7b3/6a1709c9acf0882669be9ac5/d3f29db64cbde9956de1fa3ae64a75f15141a2bb-1600x681.png" alt="回忆 @100 Elasticsearch BBQ 与 Opensearch FAISS 的结果" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt505ce8aa70898390/6a1709cb1949f73a37e7a9bb/10aff7f8c61fdac895b9ba9c5342baf239ba3ffc-2072x864.png" alt="Elasticsearch BBQ 和 Opensearch FAISS 延迟和吞吐量性能比较" /><h4>详细结果 - Recall @ 100</h4><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb2a73e29940e9d6b/6a1709cccf4f257615b2d138/8790fdf9512b850447f6875fb69969f6f1d4da5f-1600x799.png" alt="详细的延迟结果 - Recall @ 100 Elasticsearch BBQ vs Opensearch FAISS" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte2c91ca21da03d96/6a1709ce0c4857d3fc01aa39/d47032fac6c288cd4eedd9f25001e417b2fa9d65-1600x787.png" alt="详细的吞吐量结果 - Recall @ 100 Elasticsearch BBQ vs Opensearch FAISS。" /><p></p><p>工作</p><p>latency.mean</p><p>吞吐量平均值</p><p>平均调用次数</p><p>Elasticsearch-9.0-BBQ</p><p>100-1000-1000</p><p>27.82</p><p>243.22</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>100-1200-1200</p><p>31.14</p><p>224.04</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>100-1500-1500</p><p>35.98</p><p>193.99</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>100-200-200</p><p>14.18</p><p>403.86</p><p>0.88</p><p>Elasticsearch-9.0-BBQ</p><p>100-2000-2000</p><p>45.36</p><p>159.88</p><p>0.95</p><p>Elasticsearch-9.0-BBQ</p><p>100-250-250</p><p>14.77</p><p>433.06</p><p>0.90</p><p>Elasticsearch-9.0-BBQ</p><p>100-300-300</p><p>14.61</p><p>375.54</p><p>0.91</p><p>Elasticsearch-9.0-BBQ</p><p>100-500-500</p><p>18.88</p><p>340.37</p><p>0.93</p><p>Elasticsearch-9.0-BBQ</p><p>100-750-750</p><p>23.59</p><p>285.79</p><p>0.94</p><p>OpenSearch-2.19-faiss</p><p>100-1000-1000</p><p>142.90</p><p>58.48</p><p>0.95</p><p>OpenSearch-2.19-faiss</p><p>100-1200-1200</p><p>153.03</p><p>51.04</p><p>0.95</p><p>OpenSearch-2.19-faiss</p><p>100-1500-1500</p><p>181.79</p><p>43.20</p><p>0.96</p><p>OpenSearch-2.19-faiss</p><p>100-200-200</p><p>50.94</p><p>131.62</p><p>0.83</p><p>OpenSearch-2.19-faiss</p><p>100-2000-2000</p><p>232.53</p><p>33.67</p><p>0.96</p><p>OpenSearch-2.19-faiss</p><p>100-250-250</p><p>57.08</p><p>131.23</p><p>0.87</p><p>OpenSearch-2.19-faiss</p><p>100-300-300</p><p>62.76</p><p>120.10</p><p>0.89</p><p>OpenSearch-2.19-faiss</p><p>100-500-500</p><p>84.36</p><p>91.54</p><p>0.93</p><p>OpenSearch-2.19-faiss</p><p>100-750-750</p><p>111.33</p><p>69.95</p><p>0.94</p><h2>烧烤炉的改进</h2><p>自首次发布以来，BBQ 已经取得了长足的进步。在 Elasticsearch 8.16 上，为了便于比较，我们将 8.16 的基准运行与当前的基准运行放在一起，我们可以看到召回率和延迟从那时起有了怎样的改善。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9f1f7ae1bb425a3a/6a1709cf67045bde8e45c192/45a0acfe5985bff28ccada76ec4eca190fe65f72-1600x799.png" alt="以 Elasticsearch 8.16 BBQ 为基准测试 Elasticsearch 9.0 BBQ 延迟召回改进情况" /><p>在 Elasticsearch 8.18 和 9.0 中，我们重写了量化向量的核心算法。因此，8.16 版的 BBQ 已经很不错了，而最新版本则更加出色。您可以<a href="https://www.elastic.co/cn/search-labs/blog/optimized-scalar-quantization-elasticsearch">在这里</a>和<a href="https://www.elastic.co/cn/search-labs/blog/scalar-quantization-optimization">这里</a>了解相关信息。简而言之，每个矢量都通过优化的标量量化进行了单独量化。因此，用户可以在不影响性能的情况下获得更高的向量搜索准确性，使 Elasticsearch 的向量检索功能更加强大。</p><h2>结论</h2><p>在 Elasticsearch BBQ 和 OpenSearch FAISS 的性能比较中，Elasticsearch 在矢量搜索方面明显优于 OpenSearch，在各种召回级别中，Elasticsearch 的查询速度平均提高了 5 倍，吞吐量提高了 3.9 倍。</p><p>主要发现包括</p><ul><li><p><strong>Recall@10</strong>：与 OpenSearch FAISS 相比，Elasticsearch BBQ 的速度快达 5 倍（平均快 3.9 倍），吞吐量平均高出 3.2 倍。</p></li><li><p><strong>Recall@50</strong>：与 OpenSearch FAISS 相比，Elasticsearch BBQ 的速度快达 5 倍（平均快 4.2 倍），吞吐量平均高出 3.9 倍。</p></li><li><p><strong>Recall@100</strong>：与 OpenSearch FAISS 相比，Elasticsearch BBQ 的速度快达 5 倍（平均快 4.6 倍），吞吐量平均高出 3.9 倍。</p></li></ul><p>这些结果凸显了 Elasticsearch BBQ 的效率和性能优势，尤其是在高维向量搜索场景中。Elasticsearch 8.16 中引入的更好的二进制量化（BBQ）技术在保持较高排序质量的同时，大幅减少了内存（~95% ），是大规模矢量搜索应用的上佳选择。</p><p>在 Elastic，我们坚持不懈地创新，改进 Apache Lucene 和 Elasticsearch，为搜索和检索用例（包括 RAG（检索增强生成））提供最佳的向量数据库。在 Lucene 10 的基础上，我们<a href="https://www.elastic.co/cn/search-labs/blog/optimized-scalar-quantization-elasticsearch">最近取得的进步</a>大大提高了性能，使矢量搜索比以前更快、更节省空间。本博客就是这种创新的又一例证。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-bbq-vs-opensearch-faiss</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-bbq-vs-opensearch-faiss</guid>
    <category><![CDATA[向量数据库]]></category>
    <dc:creator><![CDATA[Ugo Sangiorgi]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd76ada1eebfe05cd/6a1709d1a29299ed29d00ffb/796de4829e29566f1f3efa2482f5c3e54b31b1d6-1536x1024.png" length="0" type="image/png"/>
    <pubDate>Tue, 15 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch 与 OpenSearch：向量搜索性能比较]]></title>
    <description><![CDATA[Elasticsearch 开箱即用，在向量搜索方面比 OpenSearch 快 2 倍至 12 倍]]></description>
    <content:encoded><![CDATA[<p><a href="https://www.elastic.co/search-labs/blog/elasticsearch-opensearch-vector-search-performance-comparison#up-to-12x-faster-out-of-the-box">TLDR：Elasticsearch 的速度提高了 12 倍</a> - Elastic 收到了来自社区的大量请求，要求澄清 Elasticsearch 和 OpenSearch 之间的性能差异，特别是在语义搜索/向量搜索领域，因此我们进行了这项性能测试，以提供清晰、数据驱动的对比——没有模棱两可之处，只有直接的事实来为我们的用户提供信息。结果表明，<strong>Elasticsearch 在向量搜索方面比 OpenSearch 快 12 倍</strong>，因此所需的计算资源更少。这反映了 Elastic 致力于将 Lucene 打造为搜索和检索用例的最佳向量数据库。</p><p>向量搜索正在彻底改变我们进行相似性搜索的方式，特别是在 AI 和机器学习等领域。随着向量嵌入模型的日益普及，在数百万个高维向量中进行高效搜索的能力变得至关重要。</p><p>在为向量数据库提供支持时，Elastic 和 OpenSearch 采取了显著不同的方法。Elastic 投入巨资优化 Apache Lucene 和 Elasticsearch，使其成为向量搜索应用程序的顶级选择。相比之下，OpenSearch 扩大了其关注范围，整合了其他向量搜索实现，并探索了超出 Lucene 范围的领域。我们对 Lucene 的关注具有战略意义，这使我们能够在 Elasticsearch 版本中提供高度集成的支持，从而形成一个功能更强大的组合，其中每个组件都能相互补充并增强彼此的功能。</p><p>本博客详细比较了 Elasticsearch 8.14 和 OpenSearch 2.14 的不同配置和向量引擎。在这项性能分析中，Elasticsearch 被证明是向量搜索操作的卓越平台，而即将推出的<a href="https://www.elastic.co/search-labs/blog/vector-similarity-computations-ludicrous-speed">功能</a>将更加<a href="https://www.elastic.co/search-labs/blog/elasticsearch-lucene-vector-database-gains">显著地</a>扩大差异。与 OpenSearch 相比，它在每个基准轨道上都表现出色——<strong>平均性能提高了 2 倍到 12 倍</strong>。这涉及使用不同的向量数量和维度的场景，包括 <code>so_vector</code>（2M 向量，768D）、<code>openai_vector</code>（2.5M 向量，1536D）和 <code>dense_vector</code>（10M 向量，96D），所有这些都可在<a href="https://github.com/elastic/elasticsearch-opensearch-vector-performance">此存储库</a>中找到，并附有在 Google Cloud 上配置所有所需基础架构的 Terraform 脚本和用于运行测试的 Kubernetes 清单。</p><p>本博客中详述的结果补充了<a href="https://www.elastic.co/blog/elasticsearch-opensearch-performance-gap">之前发布并经过第三方验证的研究</a>的结果。该研究表明，在最常见的搜索分析操作中，Elasticsearch 比 OpenSearch 快 40%–140%；此类操作包括文本查询、排序、范围、日期直方图和术语过滤。现在我们可以添加另一个差异化因素：向量搜索。</p><h2>开箱即用，性能提升高达 12 倍</h2><p>我们在四个向量数据集上的基准测试涉及近似 KNN 和精确 KNN 搜索，考虑了不同的大小、维度和配置，总共进行了 <code>40.189.820</code> 次未缓存的搜索请求。结果：<strong>Elasticsearch 在向量搜索中比 OpenSearch 快 12 倍</strong>，因此需要更少的计算资源。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt34b83c6eba3bcb6e/6a17d727dbb4ff18d6fb54fb/cdb26e91f085b90e9b12aeb8fee53b04d365ecae-1440x1156.webp" alt="p90 平均值" /><p>图 1：Elasticsearch 和 OpenSearch 中不同组合的 ANN 和精确 KNN 的分组任务。</p><p>像 <code>knn-10-100</code> 这样的组表示 KNN 搜索， 和 。在 HNSW 向量搜索中， 决定了查询向量要检索的最近邻居数量。它指定了要找到多少个相似向量。 设置每个段要检索的候选向量数量。更多的候选者可以提高准确性，但需要更多的计算资源。</p><p>我们还测试了不同的量化技术，并利用特定引擎进行了优化。各个轨道、任务和向量引擎的详细结果如下。</p><h2>精确 KNN 和近似 KNN</h2><p>在处理不同的数据集和用例时，向量搜索的正确方法会有所不同。在本博客中，所有标记为 <code>knn-*</code> 的任务，如 <code>knn-10-100</code>，使用 <strong>近似 KNN</strong>，而 <code>script-score-*</code> 指的是 <strong>精确 KNN</strong>，但它们之间有什么区别，为什么它们很重要？</p><p>本质上，如果您处理的是更大规模的数据集，首选方法是近似 K 最近邻 (ANN)，因为它具有更出色的可扩展性。对于可能需要过滤过程的规模较小的数据集，精确 KNN 方法是理想选择。</p><p>精确 KNN 使用暴力方法，计算数据集中一个向量与其他每个向量之间的距离。然后对这些距离进行排序，找出  个最近的邻居。虽然这种方法能确保精确匹配，但对于大型高维数据集来说，它在可扩展性方面面临挑战。然而，在很多情况下，需要使用精确 KNN：</p><ul><li><p><strong>重新评分</strong>：在涉及词汇或语义搜索后进行基于向量的重新评分时，精确 KNN 至关重要。例如，在产品搜索引擎中，可以根据文本查询（例如，关键字、类别）筛选初始搜索结果，然后使用与筛选出的项目相关的向量进行更准确的相似性评估。</p></li><li><p><strong>个性化</strong>：处理大量用户时，如果每个用户都由相对较少数量（例如 100 万）的不同向量表示，则按用户特定的元数据（例如 user_id）对索引进行排序，并使用向量进行暴力评分会变得高效。这种方法能够根据精准的向量比较，根据用户的个人偏好为用户量身定制个性化推荐或内容交付。</p></li></ul><p>因此，精确 KNN 确保了基于向量相似度的最终排名和推荐精准且符合用户偏好。</p><p>另一方面，近似 KNN（或 ANN）采用的方法使得数据搜索比精确 KNN 更快、更高效，尤其是在大型高维数据集中。ANN 并不采用蛮力方法（即测量查询与所有点之间的精确最近距离，从而带来计算和扩展挑战），而是使用某些技术来有效地重构数据集中可搜索向量的索引和维度。虽然这可能会导致轻微的不准确，但它显著提高了搜索过程的速度，使其成为处理大型数据集的有效替代方案。</p><p>在本博客中，所有表述为 <code>knn-*</code> 的任务，例如 <code>knn-10-100</code>，均使用<strong>近似 KNN</strong>，而 <code>script-score-*</code> 指的是<strong>精确 KNN</strong>。</p><h2>测试方法</h2><p>虽然 Elasticsearch 和 OpenSearch 在 BM25 搜索操作的 API 方面相似，但由于后者是前者的分支，向量搜索并非如此，因为它是在分支之后才引入的。在算法方面，OpenSearch 采取了与 Elasticsearch 不同的方法，除了 <code>lucene</code> 之外，还引入了另外两个引擎——<code>nmslib</code> 和 <code>faiss</code>，每个引擎都有其特定的配置和限制（例如，OpenSearch 中的 <code>nmslib</code> 不支持使用筛选器，而筛选器是许多用例的一项基本功能）。</p><p>这三个引擎都使用分层可导航小世界 (HNSW) 算法，该算法对于近似最近邻搜索非常高效，尤其在处理高维数据时表现出色。需要注意的是，<code>faiss</code> 还支持第二种算法 <code>ivf</code>，但由于它需要对数据集进行预训练，因此我们将仅关注 HNSW。HNSW 的核心理念是将数据组织成多层连接图表，每一层代表数据集的不同粒度。搜索从最顶层的粗略视图开始，逐步深入到越来越精细的层级，直至到达最底层。</p><p>这两个搜索引擎在受控环境中的相同条件下进行了测试，以确保测试的公平性。所采用的方法与<a href="https://www.elastic.co/blog/elasticsearch-opensearch-performance-gap#testing-methodology">之前发布的性能比较</a>类似，为 Elasticsearch、OpenSearch 和 Rally 配备了专用节点池。<a href="https://github.com/elastic/elasticsearch-opensearch-vector-performance/blob/main/terraform/main.tf">terraform 脚本</a>（与所有源一起）可用于配置具有以下功能的 Kubernetes 集群：</p><ul><li><p>1 个适用于 Elasticsearch 的节点池，包含 3 台 <code>e2-standard-32</code> 计算机（128GB RAM 和 32 个 CPU）</p></li><li><p>1 个 Node 池用于 OpenSearch，配备 3 台 <code>e2-standard-32</code> 机器（128GB RAM 和 32 个 CPU）</p></li><li><p>1 个适用于 Rally 的节点池，包含 2 台 <code>t2a-standard-16</code> 计算机（64GB RAM 和 16 个 CPU）</p></li></ul><p>每个“轨道”（或测试）的每种配置都运行了 10 次，其中包括不同的引擎、不同的配置和不同的向量类型。轨道上的任务会根据轨道的不同重复 1,000 到 10,000 次。如果某个轨道中的某个任务由于网络超时而失败，则所有任务都将被丢弃，因此所有结果都代表了顺利开始并完成的轨道。所有测试结果都经过统计验证，确保改进并非偶然。</p><h2>详细结果</h2><p>为什么要使用第 99 个百分位而不是平均延迟来进行比较？考虑一个假设的例子：某个社区的平均房价。平均价格可能表明一个昂贵的地区，但仔细观察后，可能会发现大多数房屋的价值要低得多，只有少数豪华属性抬高了平均价格。这说明了平均价格如何无法准确代表该地区房屋价值的完整范围。这就好比检查响应时间，平均值可能会掩盖关键问题。</p><h4>任务</h4><ul><li><p>近似 KNN，k:10 n:50</p></li><li><p>使用 k:10 n:100 的近似 KNN</p></li><li><p>近似 KNN，k:100 n:1000</p></li><li><p>使用 k:10 n:50 和关键字筛选器的近似 KNN</p></li><li><p>使用 k:10 n:100 和关键字筛选器的近似 KNN</p></li><li><p>使用 k:100 n:1000 和关键字筛选器的近似 KNN</p></li><li><p>使用 k:10 n:100 结合索引的近似 KNN</p></li><li><p>精确 KNN（脚本分数）</p></li></ul><h4>向量引擎</h4><ul><li><p><code>lucene</code> 在 Elasticsearch 和 OpenSearch 中，版本均为 9.10</p></li><li><p><code>faiss</code> 在 OpenSearch 中</p></li><li><p><code>nmslib</code> 在 OpenSearch 中</p></li></ul><h4>向量类型</h4><ul><li><p><code>hnsw</code> 在 Elasticsearch 和 OpenSearch 中</p></li><li><p><code>int8_hnsw</code> 在 Elasticsearch 中（采用自动 8 位量化的 HNSW：<a href="https://www.elastic.co/search-labs/blog/evaluating-scalar-quantization">链接</a>）</p></li><li><p><code>sq_fp16 hnsw </code>在 OpenSearch 中（采用自动 16 位量化的 HNSW：<a href="https://opensearch.org/docs/2.14/search-plugins/knn/knn-vector-quantization#faiss-16-bit-scalar-quantization">链接</a>）</p></li></ul><h4>开箱即用和并行分段搜索</h4><p>您可能知道，Lucene 是一个用 Java 编写的高性能文本搜索引擎库，它是 Elasticsearch、OpenSearch 和 Solr 等许多搜索平台的核心。Lucene 的核心是将数据组织成多个段，这些段本质上是独立的索引，使 Lucene 能够更高效地执行搜索。因此，当您向任何基于 Lucene 的搜索引擎发出搜索请求时，您的搜索最终将在这些段中按顺序或并行执行。</p><p>OpenSearch 将并发分段搜索作为可选标记引入，默认情况下不使用该标记，您必须使用特殊的索引设置 <code>index.search.concurrent_segment_search.enabled</code> 启用该标记，<a href="https://opensearch.org/docs/latest/search-plugins/concurrent-segment-search/">此处</a>有详细说明，但有一些<a href="https://opensearch.org/docs/latest/search-plugins/concurrent-segment-search/#other-considerations">限制</a>。</p><p>另一方面，Elasticsearch 能以<a href="https://github.com/elastic/elasticsearch/pull/101230">开箱即用的</a>方式并发搜索各网段，因此我们在本博客中进行的比较除了考虑不同的向量引擎和向量类型外，还将考虑不同的配置：</p><ul><li><p>Elasticsearch ootb：开箱即用的 Elasticsearch，支持并行分段搜索；</p></li><li><p>OpenSearch ootb：未启用并行分段搜索；</p></li><li><p>OpenSearch css：启用并发段搜索</p></li></ul><p>现在，让我们深入了解每个已测试的向量数据集的详细结果：</p><h2>250 万个向量，1536 个维度（openai_vector）</h2><p>从最简单的轨道开始，但在维度方面也是最大的，<a href="https://github.com/elastic/rally-tracks/edit/master/openai_vector">openai_vector</a>——它使用了 <a href="https://huggingface.co/datasets/BeIR/nq">NQ 数据集</a>，并通过使用 OpenAI 的 <a href="https://openai.com/blog/new-and-improved-embedding-model">text-embedding-ada-002 模型</a>生成的嵌入来丰富该数据集。它是最简单的，因为它仅测试近似 KNN，并且只有 5 个任务。它既能独立测试（不进行索引），也能与索引一起测试，并且能使用单个客户端和 8 个同时运行的客户端进行测试。</p><h3>任务</h3><ul><li><p><strong>standalone-search-knn-10-100-multiple-clients</strong>：同时使用 8 个客户端搜索 250 万个向量 (k:10, n:100)</p></li><li><p><strong>standalone-search-knn-100-1000-multiple-clients</strong>：使用 8 个客户端同时搜索 250 万个向量（k: 100，n: 1000）</p></li><li><p><strong>standalone-search-knn-10-100-single-client</strong>：使用单个客户端在 250 万个向量上搜索（k: 10，n: 100）</p></li><li><p><strong>standalone-search-knn-100-1000-single-client</strong>：使用单个客户端在 250 万个向量上搜索（k: 100，n: 1000）</p></li><li><p><strong>parallel-documents-indexing-search-knn-10-100</strong>：在 250 万个向量上搜索，同时索引另外 100,000 个文档 (k:10, n：100)</p></li></ul><p>平均 p99 性能概述如下：</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf5791848eb0c12fb/6a17d72925daab9cae08a09e/eea0b2b49c690baada3e09d6968e513bfffe51a9-1440x318.webp" alt="openai_vector 表" /><p>在此我们观察到，在执行索引（即读写）的同时进行向量搜索时，Elasticsearch 比 OpenSearch <strong>快 3 到 8 倍</strong>，而在不进行索引的情况下（:10, :100），速度提高了 <strong>2 倍到 3 倍</strong>，其中 k 和 n 相同。对于 :100 和 :1000（<em>standalone-search-knn-100-1000-single-client</em> 和 <em>standalone-search-knn-100-1000-multiple-clients</em>），Elasticsearch 的平均速度比 OpenSearch 快 <strong>2 到 7 倍</strong>。</p><p>详细结果显示了比较的确切案例和向量引擎：</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdbe41d3187ced7ec/6a17d72a445de951c44cff4c/a7a761ed631d3e6211beb83d9d93d752d10123c9-1440x1728.webp" alt="openai_vector" /><h4>召回</h4><p></p><p>knn-recall-10-100</p><p>knn-recall-100-1000</p><p>Elasticsearch-8.14.0@lucene-hnsw</p><p>0.969485</p><p>0.995138</p><p>Elasticsearch-8.14.0@lucene-int8_hnsw</p><p>0.781445</p><p>0.784817</p><p>OpenSearch-2.14.0@lucene-hnsw</p><p>0.96519</p><p>0.995422</p><p>OpenSearch-2.14.0@faiss</p><p>0.984154</p><p>0.98049</p><p>OpenSearch-2.14.0@faiss-sq_fp16</p><p>0.980012</p><p>0.97721</p><p>OpenSearch-2.14.0@nmslib</p><p>0.982532</p><p>0.99832</p><h2>一千万个向量，96 个维度 (dense_vector)</h2><p>在具有 1000 万个向量和 96 维的 <a href="https://github.com/elastic/rally-tracks/tree/master/dense_vector">dense_vector</a> 中。它基于 <a href="https://big-ann-benchmarks.com/">Yandex DEEP1B</a> 图像数据集。该数据集是从名为 <code>learn.350M.fbin</code> 的“样本数据”文件的前 1000 万个向量创建的。搜索操作使用来自“查询数据”文件查询的向量。<code>public.10K.fbin</code>。</p><p>Elasticsearch 和 OpenSearch 在此数据集上的表现都非常出色，尤其是在<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html">强制合并</a>之后，这通常是在只读索引上进行的，类似于对索引进行碎片整理，使其成为一个单一的“表”以供搜索。</p><h3>任务</h3><p>每个任务预热 100 个请求，然后测量 1000 个请求</p><ul><li><p><strong>knn-search-10-100</strong>：在 1000 万个向量上搜索（k: 10，n: 100）</p></li><li><p><strong>knn-search-100-1000</strong>：在 1000 万个向量上搜索（k：100，n：1000）</p></li><li><p><strong>knn-search-10-100-force-merge</strong>：在强制合并后搜索 1,000 万个向量 (k:10, n:100)</p></li><li><p><strong>knn-search-100-1000-force-merge</strong>：在强制合并后搜索 1000 万个向量 (k: 100, n: 1000)</p></li><li><p><strong>knn-search-100-1000-concurrent-with-indexing</strong>：在 1,000 万个向量上进行搜索，同时更新<a href="https://github.com/elastic/rally-tracks/blob/master/dense_vector/challenges/default.json#L76C36-L76C37">数据集的 5%</a> (k:100, n:1000)</p></li><li><p><strong>script-score-query</strong>：对 <a href="https://github.com/elastic/rally-tracks/blob/master/dense_vector/queries.json">2000 个特定向量</a>进行精确的 KNN 搜索。</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4629d06af85eb96c/6a17d72c6864a423e7b685dc/174995e0a2156d86359cdb7aa446dfaae6312ea4-1440x316.webp" alt="dense_vector" /><p>Elasticsearch 和 OpenSearch 在近似 KNN 上表现良好。当索引在 <em>knn-搜索-100-1000-force-merge</em> 和 <em>knn-搜索-10-100-force-merge</em> 中合并（即只有一个段）时，OpenSearch 在使用 <code>nmslib</code> 和 <code>faiss</code> 时表现优于其他，即使它们都在 15 毫秒左右并且都非常接近。</p><p>但是，当索引在 <em>knn-search-10-100</em> 和 <em>knn-search-100-1000</em> 中具有多个分段（这是索引接收其文档更新的典型情况）时，Elasticsearch 将延迟保持在约 7 毫秒和 16 毫秒左右，而所有其他 OpenSearch 引擎则较慢。</p><p>此外，当同时搜索和写入索引时 (<em>knn-search-100-1000-concurrent-with-indexing</em>)，Elasticsearch 将延迟保持在 15 毫秒以下（13.8 毫秒），比开箱即用的 OpenSearch 快近 <strong>4 倍</strong>（49.3 毫秒），并且在启用并发段搜索时仍然更快（17.9 毫秒），但由于过于接近，所以意义不大。</p><p>至于精确 KNN，差距则大得多：Elasticsearch 比 OpenSearch<strong>快 6 倍</strong>（约 260 毫秒对约 1600 毫秒）。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt254f43bcaa3dbfc2/6a17d72ddbb4ffc780fb54ff/17aec6be31117440bc4d1f99984aed95df1c4f6b-1440x1728.webp" alt="dense_vector" /><h4>召回</h4><p></p><p>knn-recall-10-100</p><p>knn-recall-100-1000</p><p>Elasticsearch-8.14.0@lucene-hnsw</p><p>0.969843</p><p>0.996577</p><p>Elasticsearch-8.14.0@lucene-int8_hnsw</p><p>0.775458</p><p>0.840254</p><p>OpenSearch-2.14.0@lucene-hnsw</p><p>0.971333</p><p>0.996747</p><p>OpenSearch-2.14.0@faiss</p><p>0.9704</p><p>0.914755</p><p>OpenSearch-2.14.0@faiss-sq_fp16</p><p>0.968025</p><p>0.913862</p><p>OpenSearch-2.14.0@nmslib</p><p>0.9674</p><p>0.910303</p><h2>200 万个向量，768 个维度 (so_vector)</h2><p>此<a href="https://github.com/elastic/rally-tracks/tree/master/so_vector">轨道</a> <code>so_vector</code> 源自于 2022 年 4 月 21 日下载的 <a href="https://archive.org/download/stackexchange/stackoverflow.com-Posts.7z">StackOverflow 帖子转储</a>。它仅包含问题文档——所有代表答案的文档都已删除。每个问题的标题都已使用句子转换器模型 <a href="https://huggingface.co/sentence-transformers/multi-qa-mpnet-base-cos-v1">multi-qa-mpnet-base-cos-v1</a> 编码成一个向量。此数据集包含前 200 万个问题。</p><p>与前一个轨道不同，这里的每个文档都包含除向量之外的其他字段，以支持诸如带筛选和混合搜索功能的近似 KNN 等测试功能。此测试中明显缺少适用于 OpenSearch 的 <code>nmslib</code>，<a href="https://opensearch.org/docs/latest/search-plugins/knn/filter-search-knn/#k-nn-search-with-filters">因为它不支持筛选器</a>。</p><h3>任务</h3><p>每个任务会预热 100 个请求，然后测量 100 个请求。请注意，为了简单起见，我们对任务进行了分组，因为测试包含 16 种搜索类型 * 2 个不同的 k 值 * 3 个不同的 n 值。</p><ul><li><p><strong>knn-10-50</strong>：在没有筛选器的情况下搜索 200 万个向量 (k:10, n:50)</p></li><li><p><strong>knn-10-50-filtered</strong>：<a href="https://github.com/elastic/rally-tracks/blob/master/so_vector/operations/default.json">使用筛选器</a>在 200 万个向量上进行搜索 (k:10, n:50)</p></li><li><p><strong>knn-10-50-after-force-merge</strong>：在强制合并并使用过滤器后，对 200 万个向量进行搜索（k: 10，n: 50）</p></li><li><p><strong>knn-10-100</strong>：在没有过滤器的情况下搜索 200 万个向量（k: 10，n: 100）</p></li><li><p><strong>KNN-10-100-filtered</strong>：在 200 万个向量上<a href="https://github.com/elastic/rally-tracks/blob/master/so_vector/operations/default.json">使用过滤器</a>进行搜索（k: 10，n: 100）</p></li><li><p><strong>knn-10-100-after-force-merge</strong>：在强制合并后，使用筛选器在 200 万个向量上进行搜索 (k:10, n:100)</p></li><li><p><strong>knn-100-1000</strong>：在没有过滤器的情况下搜索 200 万个向量（k:100，n:1000）</p></li><li><p><strong>knn-100-1000-filtered</strong>：<a href="https://github.com/elastic/rally-tracks/blob/master/so_vector/operations/default.json">使用筛选器</a>在 200 万个向量上进行搜索 (k:100, n:1000)</p></li><li><p><strong>knn-100-1000-after-force-merge</strong>：在强制合并后使用过滤器在 200 万个向量上搜索（k：100，n：1000）</p></li><li><p><strong>exact-knn</strong>：<a href="https://github.com/elastic/rally-tracks/blob/master/so_vector/operations/default.json#L56">带筛选器和不带筛选器</a>的精确 KNN 搜索。</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8b44e1306af35877/6a17d72f577262aca11bca3e/d4ed2982d55370cad4b2048b23ce97caa55017c0-1440x316.webp" alt="so_vector 表" /><p>在这项测试中，Elasticsearch <strong>始终比 OpenSearch 的开箱即用速度快</strong>，OpenSearch 仅在两种情况下更快，但差距不大（<em>knn-10-100</em> 和 <em>knn-100-1000</em>）。将<em>knn-10-50</em>、<em>knn-10-100</em> 和 <em>knn-100-1000</em> 与筛选器结合使用的任务显示出高达 <strong>7 倍</strong>的差异（112 毫秒对 803 毫秒）。</p><p>执行“强制合并”操作后，两种解决方案的性能似乎趋于平稳，这是可以理解的，从 <em>knn-10-50-after-force-merge</em>、<em>knn-10-100-after-force-merge</em> 和 <em>knn-100-1000-after-force-merge</em> 中可以明显看出这一点。在这些任务中，<code>faiss</code> 的速度更快。</p><p>在精确 KNN 的性能上差异再次明显，这次 Elasticsearch 比 OpenSearch <strong>快 13 倍</strong>（约 385 毫秒对比 5262 毫秒）。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf80ccc7c2df84559/6a17d7314b055de00d43203f/615cb9228eb05ddd2e9512b3a6a5bc88d4088a1a-1440x1440.webp" alt="so_vector" /><h4>召回</h4><p></p><p>knn-recall-10-100</p><p>knn-recall-100-1000</p><p>knn-recall-10-50</p><p>Elasticsearch-8.14.0@lucene-hnsw</p><p>1</p><p>1</p><p>1</p><p>Elasticsearch-8.14.0@lucene-int8_hnsw</p><p>1</p><p>0.986667</p><p>1</p><p>OpenSearch-2.14.0@lucene-hnsw</p><p>1</p><p>1</p><p>1</p><p>OpenSearch-2.14.0@faiss</p><p>1</p><p>1</p><p>1</p><p>OpenSearch-2.14.0@faiss-sq_fp16</p><p>1</p><p>1</p><p>1</p><p>OpenSearch-2.14.0@nmslib</p><p>0.9674</p><p>0.910303</p><p>0.976394</p><h2>Elasticsearch 和 Lucene 明显胜出</h2><p>在 Elastic，我们坚持不懈地对 Apache Lucene 和 Elasticsearch 进行创新，以确保我们能够为搜索和检索用例（包括 RAG (Retrieval-Augmented Generation)）提供一流的向量数据库。我们最近取得的进展极大地提升了性能，使向量搜索比以前<a href="https://search-labs.elastic.co/search-labs/blog/elasticsearch-lucene-vector-database-gains">更快、更节省空间</a>，这是在 Lucene 9.10 所取得的成果基础上实现的。这篇博客介绍了一项研究，该研究表明，在比较最新版本时，Elasticsearch 的速度比 OpenSearch 快多达 12 倍。</p><p>值得注意的是，这两款产品都使用相同版本的 Lucene（<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/release-notes-8.14.0.html">Elasticsearch 8.14 发行说明</a> 和 <a href="https://github.com/opensearch-project/OpenSearch/blob/2.14/release-notes/opensearch.release-notes-2.14.0.md">OpenSearch 2.14 发行说明</a>）。</p><p>Elastic 的创新步伐不仅将为我们的本地部署和 Elastic Cloud 客户提供更多服务，还将为使用我们的<a href="https://www.elastic.co/search-labs/blog/stateless-your-new-state-of-find-with-elasticsearch">无状态平台</a>的客户提供更多服务。在提供对<a href="https://www.elastic.co/search-labs/blog/int4-scalar-quantization-in-lucene">标量量化到 int4</a> 等功能的支持时，我们将进行严格的测试，以确保客户能够在不显著减少召回率的情况下使用这些技术，这与<a href="https://www.elastic.co/search-labs/blog/evaluating-scalar-quantization">我们对 int8 的测试</a>类似。</p><p>由于 AI 和机器学习应用程序的普及，向量搜索效率正成为现代搜索引擎中不可或缺的功能。对于寻求能够满足大容量、高复杂性向量数据需求的强大搜索引擎的组织来说，Elasticsearch 是最佳选择。</p><p>无论是扩展已建立的平台还是启动新项目，集成 Elasticsearch 以满足向量搜索需求都是一项战略性举措，将带来切实的长期效益。Elasticsearch 凭借其公认的性能优势，已准备好支撑搜索领域的下一波创新浪潮。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-opensearch-vector-search-performance-comparison</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-opensearch-vector-search-performance-comparison</guid>
    <category><![CDATA[向量数据库]]></category>
    <category><![CDATA[Lucene]]></category>
    <dc:creator><![CDATA[Ugo Sangiorgi]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5d70b25967c2194e/6a17d732b1e11383f879f0ca/13c3c0053e2968fb835ba2f90f34bec3a011b5c0-880x592.webp" length="0" type="image/webp"/>
    <pubDate>Wed, 26 Jun 2024 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>