MEDIUM: mux-h2: change the default initial window to 16kB

Now that we're using all available rx buffers for transfers, there's
no point anymore in advertising more than the minimum value we can
safely buffer. Let's be conservative and only rely on the dynamic
buffers to improve speed beyond the configured value, and make sure
than many streams will no longer cause unfairness.

Interestingly, the total number of wakeups has further shrunk down, but
with a different distribution. From 128k for 1000 1M transfers, it went
down to 119k, with 96k from restart_reading, 10k from done_ff and 2.6k
from snd_buf. done_ff went up by 30% and restart_reading went down by
30%.
This commit is contained in:
Willy Tarreau 2024-10-09 08:43:31 +02:00
parent 1ed9d37c88
commit 0fd66703c2
2 changed files with 22 additions and 17 deletions

View File

@ -3478,12 +3478,12 @@ tune.h2.fe.initial-window-size <number>
from HAProxy. This setting only affects payload contents (i.e. the body of
POST requests), not headers. When not set, the common default value set by
tune.h2.initial-window-size applies. It can make sense to increase this value
to allow faster uploads. The default value of 65536 allows at least 5 Mbps of
bandwidth per stream over a 100 ms ping time, and 500 Mbps for 1 ms ping
time. It doesn't affect resource usage. Using too large values may cause
clients to experience a lack of responsiveness if pages are accessed in
parallel to large uploads. It is better to use tune.h2.fe.rxbuf instead,
which does not cause any unfairness.
to allow faster uploads. The default value equals tune.bufsize (16384) and
allows at least 1.25 Mbps of bandwidth per stream over a 100 ms ping time,
and 125 Mbps for 1 ms ping time. It doesn't affect resource usage. Using too
large values may cause clients to experience a lack of responsiveness if
pages are accessed in parallel to large uploads. It is better to use
tune.h2.fe.rxbuf instead, which does not cause any unfairness.
See also: tune.h2.initial-window-size.
@ -3559,16 +3559,17 @@ tune.h2.initial-window-size <number>
and outgoing connections. This value is used for incoming connections when
tune.h2.fe.initial-window-size is not set, and by outgoing connections when
tune.h2.be.initial-window-size is not set. This setting is used both as the
initial value and as a minimum per stream. The default value is 65536, which
for uploads roughly allows at least 5 Mbps of bandwidth per stream over a
network showing a 100 ms ping time, or 500 Mbps over a 1-ms local network.
When less receive buffers than the maximum are in use, within the limits
defined by tune.h2.be.rxbuf and tune.h2.fe.rxbuf, unused buffers will be
shared between receiving streams. As such there is normally no point in
changing this default setting. Given that changing this default value will
both increase upload speeds and cause more unfairness between clients on
downloads, it is recommended to instead use the side-specific settings
tune.h2.fe.initial-window-size and tune.h2.be.initial-window-size.
initial value and as a minimum per stream. The default value equals 16384
(tune.bufsize), which for uploads roughly allows at least 1.25 Mbps of
bandwidth per stream over a network showing a 100 ms ping time, or 125 Mbps
over a 1-ms local network. When less receive buffers than the maximum are in
use, within the limits defined by tune.h2.be.rxbuf and tune.h2.fe.rxbuf,
unused buffers will be shared between receiving streams. As such there is
normally no point in changing this default setting. Given that changing this
default value will both increase upload speeds and cause more unfairness
between clients on downloads, it is recommended to instead use the side-
specific settings tune.h2.fe.initial-window-size and
tune.h2.be.initial-window-size.
tune.h2.max-concurrent-streams <number>
Sets the default HTTP/2 maximum number of concurrent streams per connection

View File

@ -463,7 +463,7 @@ struct pool_head *pool_head_h2_rx_bufs __read_mostly = NULL;
/* a few settings from the global section */
static int h2_settings_header_table_size = 4096; /* initial value */
static int h2_settings_initial_window_size = 65536; /* default initial value */
static int h2_settings_initial_window_size = 0; /* default initial value: bufsize */
static int h2_be_settings_initial_window_size = 0; /* backend's default initial value */
static int h2_fe_settings_initial_window_size = 0; /* frontend's default initial value */
static int h2_be_glitches_threshold = 0; /* backend's max glitches: unlimited */
@ -8341,6 +8341,10 @@ static int init_h2()
return (ERR_ALERT | ERR_FATAL);
}
if (!h2_settings_initial_window_size)
h2_settings_initial_window_size =
MAX(16384, global.tune.bufsize - sizeof(struct htx) - sizeof(struct htx_blk));
max_bufs = h2_fe_settings_max_concurrent_streams ?
h2_fe_settings_max_concurrent_streams :
h2_settings_max_concurrent_streams;