- From: Willy Tarreau <w@1wt.eu>
- Date: Wed, 6 Jul 2011 07:30:58 +0200
- To: "Roy T. Fielding" <fielding@gbiv.com>
- Cc: Brian Pane <brianp@brianp.net>, httpbis Group <ietf-http-wg@w3.org>
On Tue, Jul 05, 2011 at 06:39:22PM -0700, Roy T. Fielding wrote: > > As a tangential issue, I'm curious: what's the rationale for > > recommending against pipelining the first series of requests on a new > > connection in the general case? When I look at it from a performance > > perspective, optimistically pipelining seems like a quite reasonable > > tradeoff. Consider the common case of a client that has just > > determined it needs to GET several small resources from a site to > > which it doesn't already have any connection: > > The problem is that if the server does not want to support persistent > connections, then sending a lot more data than the server is willing > to consume is likely to result in a TCP RST which may cancel the buffer > before the client has finished reading the first response. Apache's > lingering close is only going to help with that some of the time. Indeed that's still an issue with most TCP stacks, but even if the server supports persistent connections, nothing prevents it from closing after any response. Some servers close after any error for instance, so in the end, the same risk exists all the time with pipelining. (...) > > In a conservative implementation, the client opens the connection, > > sends the first request, and waits for the response before deciding > > whether to pipeline the rest. In the best-case scenario, the total > > elapsed time is 3xRTT. In the worst-case scenario, where the server > > doesn't allow the persistent connection, the total elapsed time is > > 4xRTT. > > Yes, but the normal request profile is to request one page and then > parse it for a bunch of embedded requests (images, stylesheets, etc.). > In other words, when accessing a server for the first time, the client > is usually going to wait for the first response anyway. After that > first time, the client can remember how the server responded and > make a reasonable estimate of what it can do with pipelining for > later pages. Even if the resources are partitioned across multiple > servers, there is very little gained by pushing multiple requests > down the pipe right away because the connection is going to be stuck > on slow start anyway. At a customer's (3G provider) we wanted to "fill the pipe" as much as we could in both directions. We always observed significant holes that were not caused by the slow start because we already had a sufficient initial CWND. I tried hard to force them to test with pipelining, they accepted to test. We never gained anything precisely because of this first non-pipelined request. The most efficient solution always was to use many hosts for the servers. In practice, browsers establish many connections to the servers and fetch requests from these connections. when you have between 2 and 5 objects to fetch over a given connection, the browser will still fetch the first one alone then up to 4 others. This long pause between the first one and the subsequent ones really was hurting performance. What's sad was that the next hop was a transparent proxy which did support pipelining and persistent connections. But even when declared as an explicit proxy, browsers wouldn't let us pipeline from the first request. I think something is missing there, as there are scenarii where there's little or no risk to pipeline and browsers should accept to pipeline first if configured for such (typically with a proxy, or when config says always to do so). > > Thus the aggressive implementation performs 1xRTT faster in the best > > case. Yes, it wastes upstream bandwidth in the worst case, because it > > ends up sending all but one of the requests twice. But for a typical > > web browser issuing a series of GETs, upstream bandwidth is an > > abundant resource and network round trips are expensive, so I'd rather > > spend bandwidth less efficiently in the worst case to save on round > > trips in the best case. > > Reasonable people will disagree. Try convincing Jim Gettys that it > won't have an effect on network buffers. ;-) I agree with you Roy that I disagree with Brian :-) Our upstream bandwidth was limited too and in the end, by opening many connections to workaround the lack of pipelining, we were saturating it with far too many SYN-SYN/ACK-ACK and FIN-FIN-ACK sequences. The result is that we could never find a satisfying setting. We always had to trade-off between saturating upstream with TCP and leaving huge holes due to pipelining. I was a bit frustrated, I admit. Regards, Willy
Received on Wednesday, 6 July 2011 05:31:26 UTC