本文将着重介绍OpenSearch 2.12、2.13和2.14版本的性能优化,这些优化主要包括查询性能优化、向量检索优化以及写入性能优化。本文中提及的性能测试,使用的是[OpenSearch Big5工作负载](https://github.com/opensearch-project/opensearch-benchmark-workloads/tree/main/big5), 该工作负载涵盖搜索和日志分析中常见的查询类型,包括文本查询、排序、聚合、范围查询和日期直方图聚合, 从而可以提供一个客观且易于复现的性能基准测试。
## 2.14 版本中的性能改进
自OpenSearch项目启动以来, 我们已经实现了显著的性能提升,下图展示了不同查询方式的优化情况,以OpenSearch 1.0版本和90%百分位的查询延迟为基准,我们可以看到,每个类别的查询延迟都得到了降低,有些查询类别的延迟降低地更为明显,图中加粗的绿线显示的是各个查询方式延迟降低程度的几何平均值:
![1.jpg](https://dev-media.amazoncloud.cn/3b0130b82ce044bd9459c6375b9aa339_1.jpg "1.jpg")
更完整的对比测试结果,可以参阅附录。
## 查询性能优化
在OpenSearch 2.12至2.14版本中,我们对多种查询方式都进行了优化。
### Full text queries
使用全文检索类型的query比如match query或multi_match query时,如果不关心搜索结果的文档顺序与分值,可以使用OpenSearch 2.12版本引入的match_only_text字段类型,该字段类型能够大大减少index所需要的存储空间并且加快查询速度。使用match_only_text,full text queries在OpenSearch 2.12中比在2.11中快47%,比在OpenSearch 1.0中快57%。需要注意的是,match_only_text仅支持除了interval query和span queries之外的其它类型的full text queries。
### Terms aggregation
OpenSearch 2.13中使用Lucene的precaculates预计算来加速terms aggregation,基于Big5工作负载,terms aggregation提升了85到100倍。
### Date histogram aggregation
OpenSearch 2.12中对Date histogram aggregation进行了优化,基于Big5工作负载,在没有子聚合的情况下,聚合查询性能提升了10到50倍。
### Terms query
OpenSearch 2.12中针对作用于keyword类型的terms query,利用Lucene的IndexOrDocValuesQuery提升了40%的查询性能。
在OpenSearch 2.14中,继续利用IndexOrDocValuesQuery对作用于numeric,IP,boolean以及date类型的terms query进行了性能优化。
## 向量检索性能优化
向量检索是语义检索semantic search的基石,把文档编码成向量需要占用大量的存储空间,尤其是把大文档分割成小的文档之后,存储空间会大幅增加,因此降低文档向量占用的存储空间极为必要。
通过把向量中的每一位从32bit降低到16bit,OpenSearch 2.13版本把向量的存储空间降低了45%到50%。通过对比测试,我们证实这种做法对检索质量几乎没有影响,召回率仍然在95%以上,并且查询延迟没有降低。
OpenSearch 2.14还通过统一元数据的存储来提高IVFPQ和HNSWPQ向量索引的内存使用率。
使用最近邻语义搜索的用户经常希望将向量检索与其他字段的过滤结合起来,但是简单的后置过滤效率低且效果不佳。在 OpenSearch 2.9 中引入,并在 OpenSearch 2.10 中改进的efficient filtering可以在最近邻语义检索中执行过滤,在 OpenSearch 2.14 中,我们进一步增强了过滤逻辑,通过Faiss 引擎将过滤向量搜索的查询延迟在 P99 百分位上进一步降低了约 30%。
## 写入性能优化
在OpenSearch 2.7中,通过引入segment replication特性,消除了写入放大的问题,与document level的主从复制相比,写入吞吐量提升了40%。在OpenSearch 2.11中,segment replication又有了进一步的优化,允许使用Remote storage例如[Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail)来提升数据的持久性与扩展性。
## OpenSearch 2024年RoadMap
### 核心查询引擎
OpenSearch 核心查询引擎性能优化的roadmap,主要包括以下内容:
* 支持细粒度的查询执行过程监控,帮助用户诊断查询性能瓶颈以优化性能
* Tiered-caching分层缓存
* 使用Protobuf加快节点间的通信传输效率
* 通过文档重排提高查询吞吐量并降低存储成本;分析并重写负载查询;动态剪枝;count-only缓存
* 查询引擎模块化,使得未来的性能优化更加容易
可以在[GitHub](https://github.com/orgs/opensearch-project/projects/153/views/1)上查看更多关于核心查询引擎的性能优化roadmap。
### 混合检索
混合搜索结合了文本和语义向量检索,以便兼顾两者的优势。
混合检索计划进行以下功能增强和优化:
* 并行执行文本检索和向量检索,可以提高查询性能25%
* 支持对检索结果的重排序
* 检索结果的合并支持更多的算法
* 支持返回子查询的原始分数,有利于调试和调整相关性
### 向量检索
向量检索的性能和成本问题一直备受重视,因为其本身的检索延迟会比较高,且可能消耗大量的内存。
关于向量检索,目前正在进行如下优化:
* 提升向量的indexing速度达80%,并且减少indexing所需的内存
* 减少向量中每一位的bit位,从32bit降低到16bit, 8bit甚至是1bit
* 使用基于磁盘的ANN算法结合外部存储来降低存储成本
因为向量检索在很多方面都不如文本检索灵活,所以我们也在做如下优化:
* 对已压缩的向量,通过支持rerank从而提高搜索相关性
* ANN向量检索支持多租户
## 附录:基准测试和结果
本文中介绍的基准测试和结果,都是基于Big5工作负载,对比不同的OpenSearch版本以及不同的配置得到的。关于基准测试的说明如下:
* 我们使用的是[OpenSearch Benchmark](https://github.com/opensearch-project/opensearch-benchmark)进行测试, 如果使用Rally进行测试,结果可能会不同
* 针对单节点集群进行测试,以确保配置容易且结果可重现
* 集群的节点用的是[Amazon EC2 ](https://aws.amazon.com/cn/ec2/?trk=cndc-detail)c5.2xlarge(8 vCPU, 16 GB), 属于一般实例类型
* 由Big5工作负载创建出来的index都没有副本,只有主分片
* 测试过程中始终使用单个客户端,以确保文档都按照时间顺序写入
* 在使用OpenSearch Benchmark进行测试时,我们使用的是benchmarking mode(target- throughput未开启), 使得客户端可以尽可能地发送更多的请求到OpenSearch
* 分片合并策略选用的是LogByteSizeMergePolicy
* Big5工作负载原始文档大约有60GB,七千万个文档,这些数据写入OpenSearch之后,单个主分片的容量大小在15GB左右。
下表中,表1展示了不同版本的查询延迟对比结果:
<table>
<tr>
<th></th>
<th>Query type</th>
<th>OS 1.0</th>
<th>OS 2.7</th>
<th>OS 2.11</th>
<th>OS 2.12</th>
<th>OS 2.13</th>
<th>OS 2.14</th>
</tr>
<tr>
<td rowspan=5 class="left"><b>Big 5 areas mean latency, ms</b></td>
<td class="left">Text query</td>
<td>44.34</td>
<td>37.02</td>
<td>36.12</td>
<td class="green-clr bold">19.42</td>
<td class="green-clr bold">19.41</td>
<td class="green-clr bold">20.01</td>
</tr>
<tr>
<td class="left">Sorting</td>
<td>65.04</td>
<td>18.58</td>
<td>10.21</td>
<td class="green-clr bold">6.22</td>
<td class="green-clr bold">5.55</td>
<td class="green-clr bold">5.53</td>
</tr>
<tr>
<td class="left">Terms Aggregation</td>
<td>311.78</td>
<td>315.27</td>
<td>316.32</td>
<td class="light-green-clr bold">282.41</td>
<td class="green-clr bold">36.27</td>
<td class="green-clr bold">27.18</td>
</tr>
<tr>
<td class="left">Range query</td>
<td>4.06</td>
<td>4.52</td>
<td>4.32</td>
<td class="lightest-green-clr bold">3.81</td>
<td class="lightest-green-clr bold">3.44</td>
<td class="lightest-green-clr bold">3.41</td>
</tr>
<tr>
<td class="left">Date histogram</td>
<td>4812.36</td>
<td>5093.01</td>
<td>5057.62</td>
<td class="green-clr bold">310.32</td>
<td class="green-clr bold">332.41</td>
<td class="green-clr bold">141.5</td>
</tr>
<tr>
<td class="left"><b>Relative latency, compared to OS 1.0 (geo mean)</b></td>
<td></td>
<td>100%</td>
<td>78%</td>
<td>68%</td>
<td>30%</td>
<td>19%</td>
<td>15%</td>
</tr>
<tr>
<td class="left"><b>Speedup factor, compared to OS 1.0 (geo mean)</b></td>
<td></td>
<td>1.0</td>
<td>1.3</td>
<td>1.5</td>
<td>3.3</td>
<td>5.3</td>
<td>6.7</td>
</tr>
</table>
表2展示了P90延迟在不同版本中的对比结果:
<table>
<tr>
<th>Buckets</th>
<th>Query</th>
<th>OS 1.0 </th>
<th>OS 2.7</th>
<th>OS 2.11.0</th>
<th>OS 2.12.0</th>
<th>OS 2.13.0</th>
<th>OS 2.14</th>
</tr>
<tr>
<td rowspan=6><b>Text Querying</b></td>
<td class="left">default</td>
<td>2.79</td>
<td>2.65</td>
<td>2.41</td>
<td>2.5</td>
<td>2.34</td>
<td>2.27</td>
</tr>
<tr>
<td class="left">scroll</td>
<td>448.9</td>
<td>228.42</td>
<td>227.36</td>
<td>222.1</td>
<td>210.41</td>
<td>217.82</td>
</tr>
<tr>
<td class="left light-green-clr">query_string_on_message</td>
<td>180.55</td>
<td>173.6</td>
<td>168.29</td>
<td>8.72</td>
<td>9.29</td>
<td>8.22</td>
</tr>
<tr>
<td class="left">query_string_on_message_filtered</td>
<td>174.25</td>
<td>125.88</td>
<td>146.62</td>
<td>102.53</td>
<td>110.49</td>
<td>135.98</td>
</tr>
<tr>
<td class="left">query_string_on_message_filtered_sorted_num</td>
<td>238.14</td>
<td>183.62</td>
<td>180.46</td>
<td>112.39</td>
<td>120.41</td>
<td>139.95</td>
</tr>
<tr>
<td class="left">term</td>
<td>0.81</td>
<td>1.06</td>
<td>0.91</td>
<td>0.96</td>
<td>0.88</td>
<td>0.83</td>
</tr>
<tr>
<td rowspan=14><b>Sorting</b></td>
<td class="left"> desc_sort_timestamp</td>
<td>13.09</td>
<td>159.45</td>
<td>28.39</td>
<td>20.65</td>
<td>18.76</td>
<td>20.4483</td>
</tr>
<tr>
<td class="left">asc_sort_timestamp</td>
<td>993.81</td>
<td>61.94</td>
<td>78.91</td>
<td>39.78</td>
<td>36.83</td>
<td>33.79</td>
</tr>
<tr>
<td class="left">desc_sort_with_after_timestamp</td>
<td>1123.65</td>
<td>163.53</td>
<td>28.93</td>
<td>19.4</td>
<td>18.78</td>
<td>22.492</td>
</tr>
<tr>
<td class="left">asc_sort_with_after_timestamp</td>
<td>1475.51</td>
<td>42.69</td>
<td>38.55</td>
<td>6.22</td>
<td>5.55</td>
<td>5.14</td>
</tr>
<tr>
<td class="left">desc_sort_timestamp_can_match_shortcut</td>
<td>15.49</td>
<td>31.13</td>
<td>7.64</td>
<td>7.11</td>
<td>6.54</td>
<td>6.88</td>
</tr>
<tr>
<td class="left">desc_sort_timestamp_no_can_match_shortcut</td>
<td>15.29</td>
<td>30.95</td>
<td>7.63</td>
<td>7.17</td>
<td>6.53</td>
<td>6.74441</td>
</tr>
<tr>
<td class="left">asc_sort_timestamp_can_match_shortcut</td>
<td>198.59</td>
<td>32.46</td>
<td>18.93</td>
<td>12.64</td>
<td>9.45</td>
<td>8.91</td>
</tr>
<tr>
<td class="left">asc_sort_timestamp_no_can_match_shortcut</td>
<td>197.36</td>
<td>32.5</td>
<td>18.78</td>
<td>12.74</td>
<td>9.02</td>
<td>8.82</td>
</tr>
<tr>
<td class="left">sort_keyword_can_match_shortcut</td>
<td>181.18</td>
<td>2.59</td>
<td>2.37</td>
<td>2.46</td>
<td>2.18</td>
<td>2.13</td>
</tr>
<tr>
<td class="left">sort_keyword_no_can_match_shortcut</td>
<td>181.06</td>
<td>2.43</td>
<td>2.44</td>
<td>2.49</td>
<td>2.15</td>
<td>2.09</td>
</tr>
<tr>
<td class="left">sort_numeric_desc</td>
<td>36.19</td>
<td>35.15</td>
<td>23.6</td>
<td>6.04</td>
<td>5.83</td>
<td>5.78</td>
</tr>
<tr>
<td class="left">sort_numeric_asc</td>
<td>66.87</td>
<td>37.74</td>
<td>21.14</td>
<td>5.3</td>
<td>5.15</td>
<td>5.2</td>
</tr>
<tr>
<td class="left">sort_numeric_desc_with_match</td>
<td>1.23</td>
<td>1.01</td>
<td>0.99</td>
<td>0.92</td>
<td>0.85</td>
<td>0.8</td>
</tr>
<tr>
<td class="left">sort_numeric_asc_with_match</td>
<td>1.24</td>
<td>0.99</td>
<td>0.9</td>
<td>0.89</td>
<td>0.84</td>
<td>0.8</td>
</tr>
<tr>
<td rowspan=5><b>Terms aggregation</b></td>
<td class="left">multi_terms_keyword</td>
<td>0.92</td>
<td>1.1</td>
<td>1</td>
<td>1.05</td>
<td>0.91</td>
<td>0.89</td>
</tr>
<tr>
<td class="left">keyword_terms</td>
<td>2126.25</td>
<td>2117.22</td>
<td>2382.37</td>
<td>1906.71</td>
<td>12.74</td>
<td>6.96</td>
</tr>
<tr>
<td class="left">keyword_terms_low_cardinality</td>
<td>2135.16</td>
<td>2121.88</td>
<td>2338.1</td>
<td>1893.9</td>
<td>10.81</td>
<td>5.25</td>
</tr>
<tr>
<td class="left">composite_terms</td>
<td>696.37</td>
<td>668.09</td>
<td>631.23</td>
<td>572.77</td>
<td>581.24</td>
<td>551.62</td>
</tr>
<tr>
<td class="left">composite_terms_keyword</td>
<td>1012.96</td>
<td>943.35</td>
<td>900.66</td>
<td>827.16</td>
<td>861.81</td>
<td>826.18</td>
</tr>
<tr>
<td rowspan=7><b>Range queries</b></td>
<td class="left">range</td>
<td>203.29</td>
<td>170.68</td>
<td>189.77</td>
<td>115.38</td>
<td>115.2</td>
<td>125.99</td>
</tr>
<tr>
<td class="left">range_numeric</td>
<td>0.81</td>
<td>0.96</td>
<td>0.87</td>
<td>0.9</td>
<td>0.76</td>
<td>0.75</td>
</tr>
<tr>
<td class="left">keyword_in_range</td>
<td>210.69</td>
<td>179.18</td>
<td>200.37</td>
<td>123.59</td>
<td>124.66</td>
<td>134.06</td>
</tr>
<tr>
<td class="left">range_field_conjunction_big_range_big_term_query</td>
<td>0.92</td>
<td>1.13</td>
<td>0.99</td>
<td>1.01</td>
<td>0.91</td>
<td>0.82</td>
</tr>
<tr>
<td class="left">range_field_disjunction_big_range_small_term_query</td>
<td>0.82</td>
<td>1.08</td>
<td>1.04</td>
<td>1</td>
<td>0.86</td>
<td>0.81</td>
</tr>
<tr>
<td class="left">range_field_conjunction_small_range_small_term_query</td>
<td>0.83</td>
<td>1.09</td>
<td>0.93</td>
<td>0.98</td>
<td>0.85</td>
<td>0.81</td>
</tr>
<tr>
<td class="left">range_field_conjunction_small_range_big_term_query</td>
<td>0.83</td>
<td>0.98</td>
<td>0.88</td>
<td>0.91</td>
<td>0.78</td>
<td>0.78</td>
</tr>
<tr>
<td rowspan=5><b>Date histogram</b></td>
<td class="left light-green-clr">date_histogram_hourly_agg</td>
<td>3618.5</td>
<td>3664.45</td>
<td>3785.48</td>
<td>8.5</td>
<td>9.97</td>
<td>3.39</td>
</tr>
<tr>
<td class="left">date_histogram_minute_agg</td>
<td>2854.99</td>
<td>2933.76</td>
<td>2961.69</td>
<td>2518.69</td>
<td>2635.16</td>
<td>148.69</td>
</tr>
<tr>
<td class="left">composite_date_histogram_daily</td>
<td>3760.5</td>
<td>4016.42</td>
<td>3574.18</td>
<td>1.44</td>
<td>1.51</td>
<td>1.39</td>
</tr>
<tr>
<td class="left">range_auto_date_histo</td>
<td>5267.47</td>
<td>5960.21</td>
<td>6055.74</td>
<td>6784.27</td>
<td>6977.05</td>
<td>6129.29</td>
</tr>
<tr>
<td class="left">range_auto_date_histo_with_metrics</td>
<td>12612.77</td>
<td>13314.87</td>
<td>13637.23</td>
<td>13759.51</td>
<td>14662.24</td>
<td>13208.98</td>
</tr>
</table>
我们欢迎所有人对OpenSearch进行性能测试,您可以随时在我们的[OpenSearch官方论坛](https://forum.opensearch.org/)中提供反馈。
原文链接:https://opensearch.org/blog/opensearch-performance-2.14/