From ba343885e4fd000cb8baec63dcd45a879e5a5d11 Mon Sep 17 00:00:00 2001 From: Fanit Kolchina Date: Fri, 7 Jun 2024 16:19:28 -0400 Subject: [PATCH] Add tables and Ian's profile Signed-off-by: Fanit Kolchina --- _community_members/hoangia.md | 23 + .../2024-06-07-opensearch-performance-2.14.md | 514 +++++++++++++++++- assets/media/community/members/hoangia.jpg | Bin 0 -> 19239 bytes 3 files changed, 518 insertions(+), 19 deletions(-) create mode 100644 _community_members/hoangia.md create mode 100644 assets/media/community/members/hoangia.jpg diff --git a/_community_members/hoangia.md b/_community_members/hoangia.md new file mode 100644 index 0000000000..b11275dc7c --- /dev/null +++ b/_community_members/hoangia.md @@ -0,0 +1,23 @@ +--- +short_name: hoangia +name: Ian Hoang +photo: /assets/media/community/members/hoangia.jpg +title: 'OpenSearch Community Member: Ian Hoang' +primary_title: Ian Hoang +breadcrumbs: + icon: community + items: + - title: Community + url: /community/index.html + - title: Members + url: /community/members/index.html + - title: 'Ian Hoang's Profile' + url: '/community/members/ian-hoang.html' +github: IanHoang +job_title_and_company: 'Software engineer at AWS' +personas: + - author +permalink: '/community/members/ian-hoang.html' +--- +**Ian Hoang** is a software engineer at AWS working on OpenSearch. + \ No newline at end of file diff --git a/_posts/2024-06-07-opensearch-performance-2.14.md b/_posts/2024-06-07-opensearch-performance-2.14.md index 3d736105f8..5fb36755e7 100644 --- a/_posts/2024-06-07-opensearch-performance-2.14.md +++ b/_posts/2024-06-07-opensearch-performance-2.14.md @@ -5,6 +5,7 @@ authors: - sisurab - pallp - macrakis + - hoangia date: 2024-06-07 categories: - technical-posts @@ -18,15 +19,64 @@ OpenSearch covers a broad range of functionality for applications involving docu We evaluated performance improvements using the [OpenSearch Big5 workload](https://github.com/opensearch-project/opensearch-benchmark-workloads/tree/main/big5), which covers the types of queries common in search and log analytics, including text queries, sorting, term aggregations, range queries, and date histograms. This provides an objective and easy-to-replicate benchmark for performance work. + + ## Performance improvements through 2.14 Since the inception of the OpenSearch Project, we have achieved significant increases in speed. -The following graph shows the relative improvements by query category as the 90th percentile latencies, with a baseline of OpenSearch 1.0. Every category improved considerably, some dramatically. Full numbers are available in the data appendix. +The following graph shows the relative improvements by query category as the 90th percentile latencies, with a baseline of OpenSearch 1.0. Every category improved considerably, some dramatically. For the full results, see the [Appendix](#appendix-benchmark-tests-and-results). The heavy green line summarizes the overall improvements as the geometric mean of the individual categories of improvement, showing continuous progress in performance. -OpenSearch performance improvements up to 2.14{:style="width: 100%; max-width: 750px; height: auto;"} +OpenSearch performance improvements up to 2.14{:style="width: 100%; max-width: 750px; height: auto;"} ## Queries @@ -40,7 +90,7 @@ However, many applications do not need this additional information---it's enough For these applications, OpenSearch 2.12 introduced the [`match_only_text`](https://opensearch.org/docs/latest/field-types/supported-field-types/match-only-text) field. This field type dramatically reduces the space needed for indexes and speeds up query execution because there is no complicated scoring for relevance ranking. At the same time, it supports all standard text query types, except for interval and span queries. -**Using `match_only_text`, text queries are 47% faster in OpenSearch 2.12 than in 2.11 and 57% faster than in OpenSearch 1.0**. +Using `match_only_text`, text queries are 47% faster in OpenSearch 2.12 than in 2.11 and 57% faster than in OpenSearch 1.0. ### Term aggregations @@ -48,15 +98,15 @@ Term aggregations are an important tool in data analytics because they allow you OpenSearch 2.13 speeds up term aggregations for global term aggregations in immutable collections such as log data. This is an important and common analytics use case. OpenSearch gains this efficiency by using the term frequencies that Lucene precalculates. -**Evaluating term aggregations on Big5 data shows speed improvements of a factor of 85 to 100**. +Evaluating term aggregations on Big5 data shows speed improvements of a factor of 85 to 100. ### Date histograms -Date histograms are OpenSearch’s way of grouping data by date. Almost every Dashboard or Discover visualization in OpenSearch Dashboards depends on this functionality. For example, you might want to aggregate the logs of every HTTP request sent to your site by week. **Date histogram optimizations in OpenSearch 2.12 provide speed improvements ranging from 10 to 50 times on the Big5 benchmark**, in cases where there are no sub-aggregations into range filters. +Date histograms are OpenSearch’s way of grouping data by date. Almost every Dashboard or Discover visualization in OpenSearch Dashboards depends on this functionality. For example, you might want to aggregate the logs of every HTTP request sent to your site by week. Date histogram optimizations in OpenSearch 2.12 provide speed improvements ranging from 10 to 50 times on the Big5 benchmark, in cases where there are no sub-aggregations into range filters. ### Multi-term queries and numeric fields -Multi-term queries are commonly used in analytics to simultaneously aggregate by many terms, often retrieving only the top *n* results. **OpenSearch 2.12 accelerates multi-term queries on keyword fields by over 40%** by taking advantage of Lucene's IndexOrDocValuesQuery. +Multi-term queries are commonly used in analytics to simultaneously aggregate by many terms, often retrieving only the top *n* results. OpenSearch 2.12 accelerates multi-term queries on keyword fields by over 40% by taking advantage of Lucene's IndexOrDocValuesQuery. In version 2.14, we also use the IndexOrDocValuesQuery to increase search speed on numeric, IP, Boolean, and date fields, even when the fields are not indexed. This means that you can save storage space by not creating indexes for less commonly used search fields. @@ -68,7 +118,7 @@ Document vectors can require a lot of storage space, especially when documents a ### Vector search cost reduction -**By reducing the vector elements from 32-bit to 16-bit (fp16) floating-point numbers, OpenSearch 2.13 reduces the amount of storage required by 45--50%**. Our experiments show that this has little or no effect on the quality of the results: Recall remains above 95%, and query latency is unaffected. +By reducing the vector elements from 32-bit to 16-bit (fp16) floating-point numbers, OpenSearch 2.13 reduces the amount of storage required by 45--50%. Our experiments show that this has little or no effect on the quality of the results: Recall remains above 95%, and query latency is unaffected. OpenSearch 2.14 also improves the memory usage of IVFPQ and HNSWPQ vector indexes by unifying the storage of index metadata. @@ -103,12 +153,12 @@ We are planning the following enhancements: Hybrid search combines lexical and semantic vector search in order to get the best of both worlds. Highly specific names---like part numbers---are best found using lexical search, while broader queries are often best handled by semantic vector search. We have supported hybrid search since OpenSearch 2.10. -We are planning to enhance hybrid search in the following ways: +We are planning the following hybrid search enhancements: - By executing lexical and vector searches in parallel, we can achieve a latency improvement of up to 25%. -- We will support resorting of hybrid query results. -- We will support additional algorithms for combining query results. In particular, reciprocal rank fusion has shown good results for some applications. -- We will return the raw scores of subqueries, which are useful for debugging and relevance tuning. +- Supporting resorting of hybrid query results. +- Supporting additional algorithms for combining query results. In particular, reciprocal rank fusion has shown good results for some applications. +- Returning the raw scores of subqueries, which are useful for debugging and relevance tuning. ### Vector search @@ -135,7 +185,7 @@ While we're continuing to expand OpenSearch functionality, we are also investing The OpenSearch team at AWS works in collaboration with the larger OpenSearch community. Without your contributions to testing, feedback, and development, OpenSearch would not be where it is today. Thank you. -Stay tuned to our blog and GitHub for further updates and insights into our progress and future plans. +Stay tuned to our [blog](https://opensearch.org/blog/) and [GitHub](https://github.com/orgs/opensearch-project/projects/153/views/1) for further updates and insights into our progress and future plans. ## Appendix: Benchmark tests and results @@ -152,10 +202,436 @@ This section provides detailed information about the performance benchmarks we u The following table presents the latency comparison. - - -The following table presents benchmarking results by query category. - - - -If you decide to run your own benchmarking tests, please feel free to share the results with us. As always, we welcome your feedback and contributions. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Query typeOS 1.0OS 2.7OS 2.11OS 2.12OS 2.13OS 2.14
Big 5 areas mean latency, msText query44.3437.0236.1219.4219.4120.01
Sorting65.0418.5810.216.225.555.53
Terms Aggregation311.78315.27316.32282.4136.2727.18
Range query4.064.524.323.813.443.41
Date histogram4812.365093.015057.62310.32332.41141.5
Relative latency, compared to OS 1.0 (geo mean)100%78%68%30%19%15%
Speedup factor, compared to OS 1.0 (geo mean)1.01.31.53.35.36.7
+ +The following table presents benchmarking results by query category. It shows the P90 Service Time (ms) values. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BucketsQueryOS 1.0 OS 2.7OS 2.11.0OS 2.12.0OS 2.13.0OS 2.14
Text Queryingdefault2.792.652.412.52.342.27
scroll448.9228.42227.36222.1210.41217.82
query_string_on_message180.55173.6168.298.729.298.22
query_string_on_message_filtered174.25125.88146.62102.53110.49135.98
query_string_on_message_filtered_sorted_num238.14183.62180.46112.39120.41139.95
term0.811.060.910.960.880.83
Sorting desc_sort_timestamp13.09159.4528.3920.6518.7620.4483
asc_sort_timestamp993.8161.9478.9139.7836.8333.79
desc_sort_with_after_timestamp1123.65163.5328.9319.418.7822.492
asc_sort_with_after_timestamp1475.5142.6938.556.225.555.14
desc_sort_timestamp_can_match_shortcut15.4931.137.647.116.546.88
desc_sort_timestamp_no_can_match_shortcut15.2930.957.637.176.536.74441
asc_sort_timestamp_can_match_shortcut198.5932.4618.9312.649.458.91
asc_sort_timestamp_no_can_match_shortcut197.3632.518.7812.749.028.82
sort_keyword_can_match_shortcut181.182.592.372.462.182.13
sort_keyword_no_can_match_shortcut181.062.432.442.492.152.09
sort_numeric_desc36.1935.1523.66.045.835.78
sort_numeric_asc66.8737.7421.145.35.155.2
sort_numeric_desc_with_match1.231.010.990.920.850.8
sort_numeric_asc_with_match1.240.990.90.890.840.8
Terms aggregationmulti_terms_keyword0.921.111.050.910.89
keyword_terms2126.252117.222382.371906.7112.746.96
keyword_terms_low_cardinality2135.162121.882338.11893.910.815.25
composite_terms696.37668.09631.23572.77581.24551.62
composite_terms_keyword1012.96943.35900.66827.16861.81826.18
Range queriesrange203.29170.68189.77115.38115.2125.99
range_numeric0.810.960.870.90.760.75
keyword_in_range210.69179.18200.37123.59124.66134.06
range_field_conjunction_big_range_big_term_query0.921.130.991.010.910.82
range_field_disjunction_big_range_small_term_query0.821.081.0410.860.81
range_field_conjunction_small_range_small_term_query0.831.090.930.980.850.81
range_field_conjunction_small_range_big_term_query0.830.980.880.910.780.78
Date histogramdate_histogram_hourly_agg3618.53664.453785.488.59.973.39
date_histogram_minute_agg2854.992933.762961.692518.692635.16148.69
composite_date_histogram_daily3760.54016.423574.181.441.511.39
range_auto_date_histo5267.475960.216055.746784.276977.056129.29
range_auto_date_histo_with_metrics12612.7713314.8713637.2313759.5114662.2413208.98
+ +If you decide to run your own benchmarking tests, please feel free to share the results with us. As always, we welcome your feedback and contributions and we'd love to hear from you in the [OpenSearch Forum](https://forum.opensearch.org/). diff --git a/assets/media/community/members/hoangia.jpg b/assets/media/community/members/hoangia.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e4715af09a5eb18b43ca53d7d723997ea25b8881 GIT binary patch literal 19239 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 TDYp{1Tn4B^9CfNQcR&BxzC$62 literal 0 HcmV?d00001