alts: Release read buffer when blocked on socket read#8964
Open
arjan-bal wants to merge 2 commits intogrpc:masterfrom
Open
alts: Release read buffer when blocked on socket read#8964arjan-bal wants to merge 2 commits intogrpc:masterfrom
arjan-bal wants to merge 2 commits intogrpc:masterfrom
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #8964 +/- ##
==========================================
- Coverage 83.42% 82.51% -0.91%
==========================================
Files 410 412 +2
Lines 32572 32645 +73
==========================================
- Hits 27172 26938 -234
- Misses 4030 4077 +47
- Partials 1370 1630 +260
🚀 New features to boost your workflow:
|
a937698 to
bc023c9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Normally, since the Go
net.Conninterface provides the abstraction of a blocking read to hide the complexity of non-blocking I/O (epoll, kqueue), users need to pass a read buffer to thenet.Conn.Readcall. Even when the TCP socket doesn't have data, the application needs to hold onto the read buffer. This results in the ALTS conn and the gRPC HTTP/2 stack holding on to 32KB read buffers each, even for non-readable transports.Solution
On Unix platforms, there is a RawConn interface that exposes a non-blocking mechanism. The idea is that the Go runtime will call a user-registered callback when the socket is readable. gRPC can use this callback to allocate a buffer from the pool and return it once it has passed the plaintext to the HTTP/2 layer. The same RawConn interface is also available in other OSs, but with slightly different method signatures. In the future, we can add the same optimization for them and have CI runners to catch regressions.
The main abstraction that allows these non-memory-pinning reads is the following interface:
In this PR, an implementation is provided that wraps a
RawConn. This allows the ALTS conn to perform efficient reads.In a future PR, the following changes will enable getting rid of the bufio.Reader in gRPC:
ReadyReaderwill be implemented by the ALTS conn.ReadOnReady()instead ofRead()on the underlying conn, if supported, to delay the re-allocation of the buffer.Benchmarks
The following micro-benchmarks show no regression in QPS (LargeMessage test) and a significant reduction in memory usage while performing reads (ReadMemoryUsage). There is an increase in 2 allocs in conn construction due to the use of pointer fields for the
ReadyReaderand read buffer handle, but these happen only when creating a subchannel, not per-RPC. There is an increase in sec/op for theWriteMemoryUsagetest, but these tests are not meant to measure conn construction time, only the memory effeciency.In a real-world benchmark, where a GCS directpath client downloads a file in a loop, the average "in use" memory falls from ~35MB to ~20MB.
RELEASE NOTES: