• Tom Bergan's avatar
    http2: add configurable knobs for the server's receive window · 906cda95
    Tom Bergan authored
    Upload performance is poor when BDP is higher than the flow-control window.
    Previously, the server's receive window was fixed at 64KB, which resulted in
    very poor performance for high-BDP links. The receive window now defaults to
    1MB and is configurable. The per-connection and per-stream windows are
    configurable separately (both default to 1MB as suggested in golang/go#16512).
    
    Previously, the server created a "fixedBuffer" for each request body. This is no
    longer a good idea because a fixedBuffer has fixed size, which means individual
    streams cannot use varying amounts of the available connection window. To
    overcome this limitation, I replaced fixedBuffer with "dataBuffer", which grows
    and shrinks based on current usage. The worst-case fragmentation of dataBuffer
    is 32KB wasted memory per stream, but I expect that worst-case will be rare.
    
    A slightly modified version of adg@'s grpcbench program shows a dramatic
    improvement when increasing from a 64KB window to a 1MB window, especially at
    higher latencies (i.e., higher BDPs). Network latency was simulated with netem,
    e.g., `tc qdisc add dev lo root netem delay 16ms`.
    
    Duration        Latency Proto           H2 Window
    
    11ms±4.05ms     0s      HTTP/1.1        -
    17ms±1.95ms     0s      HTTP/2.0        65535
    8ms±1.75ms      0s      HTTP/2.0        1048576
    
    10ms±1.49ms     1ms     HTTP/1.1        -
    47ms±2.91ms     1ms     HTTP/2.0        65535
    10ms±1.77ms     1ms     HTTP/2.0        1048576
    
    15ms±1.69ms     2ms     HTTP/1.1        -
    88ms±11.29ms    2ms     HTTP/2.0        65535
    15ms±1.18ms     2ms     HTTP/2.0        1048576
    
    23ms±1.42ms     4ms     HTTP/1.1        -
    152ms±0.77ms    4ms     HTTP/2.0        65535
    23ms±0.94ms     4ms     HTTP/2.0        1048576
    
    40ms±1.54ms     8ms     HTTP/1.1        -
    288ms±1.67ms    8ms     HTTP/2.0        65535
    39ms±1.29ms     8ms     HTTP/2.0        1048576
    
    72ms±1.13ms     16ms    HTTP/1.1        -
    559ms±0.68ms    16ms    HTTP/2.0        65535
    71ms±1.12ms     16ms    HTTP/2.0        1048576
    
    136ms±1.15ms    32ms    HTTP/1.1        -
    1104ms±1.62ms   32ms    HTTP/2.0        65535
    135ms±0.96ms    32ms    HTTP/2.0        1048576
    
    264ms±0.95ms    64ms    HTTP/1.1        -
    2191ms±2.08ms   64ms    HTTP/2.0        65535
    263ms±1.57ms    64ms    HTTP/2.0        1048576
    
    Fixes golang/go#16512
    Updates golang/go#17985
    Updates golang/go#18404
    
    Change-Id: Ied385aa94588337e98dad9475cf2ece2f39ba346
    Reviewed-on: https://go-review.googlesource.com/37226Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
    Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    906cda95
server.go 83.6 KB