New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
investigate smarter buffer usage #83
Comments
In gitlab by @Geal on Nov 4, 2016, 12:50 First experiment in 3270bf7: assert that the back->front buffer is empty and unused when handling the request, and the front->back buffer is empty and unused when handling the response if it works, it means we can reuse the same buffer for both directions, and halve the memory usage (using two buffers was a safe but wasteful solution). This experiment will probably not work in the websocket case, where data can go back and forth at any time |
In gitlab by @Geal on Jan 11, 2017, 10:34 That first experiment worked, and with the protocol upgrades, I can specify that websocket piping needs two buffers, while HTTP only needs one. |
In gitlab by @Geal on Jan 11, 2017, 10:34 next thing to experiment: as indicated in https://eklitzke.org/goroutines-nonblocking-io-and-memory-usage give back the buffer to the pool after a request ended, get a buffer to the pool at the beginning of the next keepalive request. Question: what happens under high load? How costly is it to release a buffer or get one from the pool? Should the buffer be released after a timeout? |
so #10 is at odds with the experiment in 3270bf7 because the client might send the body right after sending the request anyway. Of course, that behaviour is wrong, since the client is supposed to wait for the server to answer before sending the body. So we can just ignore a misbehaving client who does that? |
other thing to note: in some cases, the server could send an answer before receiving the whole request (example: to refuse a big file upload) |
so I think we could remove the double buffer usage now, since the assert have been in use for a long time and have not really triggered (except when caused by unrelated bugs).
This change might be a better fit for a future version, instead of the current release. That will leave us an opportunity for nice optimizations |
a bit more info about that issue, since the asserts have run long enough now. The asserts mainly trigger in 2 cases:
So the main reason we could have two buffers (front->back and back->front) at once to handle a session would be supporting HTTP pipelining. As a side note, here's the current hack I have to support pipelining, it's not too bad:
I think I found a good solution, I'll write more about it later today. |
so, here's the idea: make the buffers optional for the HTTP implementation, and allocate them as needed. Here's how it would play out:
This solution would have multiple benefits:
I'm not planning on implementing this right away, but first I'd like to add a metric to track the buffer pool usage, then we'll see more easily if this has an effect. |
we now have enough data, see #83 for more information
HTTP pipelining is implemented in 996c9e7 |
this is done since 3b88968 |
In gitlab by @Geal on Nov 3, 2016, 16:54
untested idea: the buffers are mainly used to parse headers, while the rest of the data can be transferred by splice() (on Linux). So keeping two buffers (one for front->back, one for back->front) could be a bit wasteful.
The proxy could request one buffer from the pool to parse request headers, transfer the headers to the backend, then:
a few unknowns in this:
The text was updated successfully, but these errors were encountered: