From 24a616b056d06738b8dc3efda087d1d23ec7e72c Mon Sep 17 00:00:00 2001 From: Adi Suissa-Peleg Date: Tue, 25 May 2021 23:42:19 -0400 Subject: [PATCH 1/4] http: setting default lazy headermap threshold to 3 Signed-off-by: Adi Suissa-Peleg --- docs/root/version_history/current.rst | 3 +++ source/common/http/header_map_impl.h | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 72d6060e75484..88b17d23a5e4f 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -30,6 +30,9 @@ Minor Behavior Changes ``envoy.reloadable_features.send_strict_1xx_and_204_response_headers`` (do not send 1xx or 204 responses with these headers). Both are true by default. * http: serve HEAD requests from cache. +* http: set the default lazy headermap threshold to 3, which defines the minimal number of headers in a + request/response/trailers required for using a dictionary in addition to the list. Setting the + `envoy.http.headermap.lazy_map_min_size` runtime feature to a non-negative number will override the default value. * listener: respect the :ref:`connection balance config ` defined within the listener where the sockets are redirected to. Clear that field to restore the previous behavior. * tcp: switched to the new connection pool by default. Any unexpected behavioral changes can be reverted by setting runtime guard ``envoy.reloadable_features.new_tcp_connection_pool`` to false. diff --git a/source/common/http/header_map_impl.h b/source/common/http/header_map_impl.h index 2f52e70c66691..e8e34d0830a60 100644 --- a/source/common/http/header_map_impl.h +++ b/source/common/http/header_map_impl.h @@ -200,8 +200,8 @@ class HeaderMapImpl : NonCopyable { HeaderList() : pseudo_headers_end_(headers_.end()), - lazy_map_min_size_(static_cast(Runtime::getInteger( - "envoy.http.headermap.lazy_map_min_size", std::numeric_limits::max()))) {} + lazy_map_min_size_(static_cast( + Runtime::getInteger("envoy.http.headermap.lazy_map_min_size", 3))) {} template bool isPseudoHeader(const Key& key) { return !key.getStringView().empty() && key.getStringView()[0] == ':'; From 6aa6a87c89e57aa906694b0ff6c70ab498538415 Mon Sep 17 00:00:00 2001 From: Adi Suissa-Peleg Date: Tue, 13 Jul 2021 14:58:13 -0400 Subject: [PATCH 2/4] Adding more docs Signed-off-by: Adi Suissa-Peleg --- .../arch_overview/http/http_connection_management.rst | 11 +++++++++++ source/common/http/header_map_impl.h | 2 +- source/docs/header_map.md | 6 ++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/root/intro/arch_overview/http/http_connection_management.rst b/docs/root/intro/arch_overview/http/http_connection_management.rst index f25d721cc52ec..502815edda680 100644 --- a/docs/root/intro/arch_overview/http/http_connection_management.rst +++ b/docs/root/intro/arch_overview/http/http_connection_management.rst @@ -245,3 +245,14 @@ Timeouts Various configurable timeouts apply to an HTTP connection and its constituent streams. Please see :ref:`this FAQ entry ` for an overview of important timeout configuration. + +HTTP header map settings +------------------------ + +Envoy maintains the insertion order of headers (and pseudo headers that begin with ":") in the +HTTP header map using a linked list data-structure, which is very fast when the number of headers +is small. In addition it can use a map data-structure to ensure fast access to the various headers. +The map will be used once the number of headers in a HTTP request/response reaches the value of the +``envoy.http.headermap.lazy_map_min_size`` runtime feature. The default threshold value is set to +3, as previous experiments empirically showed that this value provides good performance for many +use-cases. diff --git a/source/common/http/header_map_impl.h b/source/common/http/header_map_impl.h index e8e34d0830a60..59c08c89c6f40 100644 --- a/source/common/http/header_map_impl.h +++ b/source/common/http/header_map_impl.h @@ -182,7 +182,7 @@ class HeaderMapImpl : NonCopyable { * List of HeaderEntryImpl that keeps the pseudo headers (key starting with ':') in the front * of the list (as required by nghttp2) and otherwise maintains insertion order. * When the list size is greater or equal to the envoy.http.headermap.lazy_map_min_size runtime - * feature value (or uint32_t max value if not set), all headers are added to a map, to allow + * feature value (defaults to 3, if not set), all headers are added to a map, to allow * fast access given a header key. Once the map is initialized, it will be used even if the number * of headers decreases below the threshold. * diff --git a/source/docs/header_map.md b/source/docs/header_map.md index de2a52fe27ea4..2a5eef11500e9 100644 --- a/source/docs/header_map.md +++ b/source/docs/header_map.md @@ -3,6 +3,8 @@ The Envoy header map implementation (`HeaderMapImpl`) has the following properties: * Headers are stored in a linked list (`HeaderList`) in the order they are added, with pseudo headers kept at the front of the list. +* Once the number of headers is at least the runtime configured feature `envoy.http.headermap.lazy_map_min_size`, + the header map will also use a map (`HeaderLazyMap`), in addition to the linked list, for faster access to the headers. * O(1) direct access is possible for common headers needed during data plane processing. This is provided by a table of pointers that reach directly into a linked list that is populated when headers are added or removed from the map. When O(1) headers are accessed by direct method @@ -12,8 +14,8 @@ The Envoy header map implementation (`HeaderMapImpl`) has the following properti request trailers, response headers, and response trailers) via core code and extensions (`CustomInlineHeaderRegistry`). Each registered header increases the size of the table by the size of a single pointer. * Operations that search, replace, etc. for a header by name that is not one of the O(1) headers - will incur an O(N) search through the linked list. This is an implementation deficiency for - certain usage patterns that will be improved in future changes. + will either incur an O(N) search through the linked list if the number of headers is below `envoy.http.headermap.lazy_map_min_size`, + and O(1) map access otherwise. ## Implementation details From a17e81e0f40e5aca23e8e7c4057d4535fd1f9847 Mon Sep 17 00:00:00 2001 From: Adi Suissa-Peleg Date: Tue, 13 Jul 2021 20:29:11 -0400 Subject: [PATCH 3/4] Adding tag Signed-off-by: Adi Suissa-Peleg --- .../arch_overview/http/http_connection_management.rst | 2 ++ docs/root/version_history/current.rst | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/root/intro/arch_overview/http/http_connection_management.rst b/docs/root/intro/arch_overview/http/http_connection_management.rst index 502815edda680..bc2731b9e0412 100644 --- a/docs/root/intro/arch_overview/http/http_connection_management.rst +++ b/docs/root/intro/arch_overview/http/http_connection_management.rst @@ -246,6 +246,8 @@ Various configurable timeouts apply to an HTTP connection and its constituent st :ref:`this FAQ entry ` for an overview of important timeout configuration. +.. _arch_overview_http_header_map_settings: + HTTP header map settings ------------------------ diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 716da64ece174..9528d9bfbfa0b 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -34,9 +34,10 @@ Minor Behavior Changes ``envoy.reloadable_features.send_strict_1xx_and_204_response_headers`` (do not send 1xx or 204 responses with these headers). Both are true by default. * http: serve HEAD requests from cache. -* http: set the default lazy headermap threshold to 3, which defines the minimal number of headers in a - request/response/trailers required for using a dictionary in addition to the list. Setting the - `envoy.http.headermap.lazy_map_min_size` runtime feature to a non-negative number will override the default value. +* http: set the default :ref:`lazy headermap threshold ` to 3, + which defines the minimal number of headers in a request/response/trailers required for using a + dictionary in addition to the list. Setting the `envoy.http.headermap.lazy_map_min_size` runtime + feature to a non-negative number will override the default value. * http: stop sending the transfer-encoding header for 304. This behavior can be temporarily reverted by setting ``envoy.reloadable_features.no_chunked_encoding_header_for_304`` to false. * http: the behavior of the ``present_match`` in route header matcher changed. The value of ``present_match`` is ignored in the past. The new behavior is ``present_match`` performed when value is true. absent match performed when the value is false. Please reference :ref:`present_match From 5802ac354d81aebd76b335897833c76cc5870cd4 Mon Sep 17 00:00:00 2001 From: Adi Suissa-Peleg Date: Wed, 14 Jul 2021 11:52:43 -0400 Subject: [PATCH 4/4] Removing non-needed entries after merging new release Signed-off-by: Adi Suissa-Peleg --- docs/root/version_history/current.rst | 30 --------------------------- 1 file changed, 30 deletions(-) diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 20c548b2cd1c3..b4360a9bdc5e8 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -9,40 +9,10 @@ Minor Behavior Changes ---------------------- *Changes that may cause incompatibilities for some users, but should not for most* -* access_log: add new access_log command operator ``%REQUEST_TX_DURATION%``. -* access_log: remove extra quotes on metadata string values. This behavior can be temporarily reverted by setting ``envoy.reloadable_features.unquote_log_string_values`` to false. -* admission control: added :ref:`admission control ` whose default value is 80%, which means that the upper limit of the default rejection probability of the filter is changed from 100% to 80%. -* aws_request_signing: requests are now buffered by default to compute signatures which include the - payload hash, making the filter compatible with most AWS services. Previously, requests were - never buffered, which only produced correct signatures for requests without a body, or for - requests to S3, ES or Glacier, which used the literal string ``UNSIGNED-PAYLOAD``. Buffering can - be now be disabled in favor of using unsigned payloads with compatible services via the new - ``use_unsigned_payload`` filter option (default false). -* cluster: added default value of 5 seconds for :ref:`connect_timeout `. -* dns: changed apple resolver implementation to not reuse the UDS to the local DNS daemon. -* dns cache: the new :ref:`dns_query_timeout ` option has a default of 5s. See below for more information. -* http: disable the integration between :ref:`ExtensionWithMatcher ` - and HTTP filters by default to reflects its experimental status. This feature can be enabled by seting - ``envoy.reloadable_features.experimental_matching_api`` to true. -* http: replaced setting ``envoy.reloadable_features.strict_1xx_and_204_response_headers`` with settings - ``envoy.reloadable_features.require_strict_1xx_and_204_response_headers`` - (require upstream 1xx or 204 responses to not have Transfer-Encoding or non-zero Content-Length headers) and - ``envoy.reloadable_features.send_strict_1xx_and_204_response_headers`` - (do not send 1xx or 204 responses with these headers). Both are true by default. -* http: serve HEAD requests from cache. * http: set the default :ref:`lazy headermap threshold ` to 3, which defines the minimal number of headers in a request/response/trailers required for using a dictionary in addition to the list. Setting the `envoy.http.headermap.lazy_map_min_size` runtime feature to a non-negative number will override the default value. -* http: stop sending the transfer-encoding header for 304. This behavior can be temporarily reverted by setting - ``envoy.reloadable_features.no_chunked_encoding_header_for_304`` to false. -* http: the behavior of the ``present_match`` in route header matcher changed. The value of ``present_match`` is ignored in the past. The new behavior is ``present_match`` performed when value is true. absent match performed when the value is false. Please reference :ref:`present_match - `. -* listener: added an option when balancing across active listeners and wildcard matching is used to return the listener that matches the IP family type associated with the listener's socket address. Any unexpected behavioral changes can be reverted by setting runtime guard ``envoy.reloadable_features.listener_wildcard_match_ip_family`` to false. -* listener: respect the :ref:`connection balance config ` - defined within the listener where the sockets are redirected to. Clear that field to restore the previous behavior. -* tcp: switched to the new connection pool by default. Any unexpected behavioral changes can be reverted by setting runtime guard ``envoy.reloadable_features.new_tcp_connection_pool`` to false. -* tracing: add option :ref:`use_request_id_for_trace_sampling ` whether to use sampling policy based on :ref:`x-request-id` or not. Bug Fixes ---------