[#1472] fix(server): Inaccurate flow control leads to Shuffle server OOM when enabling Netty#1519
[#1472] fix(server): Inaccurate flow control leads to Shuffle server OOM when enabling Netty#1519rickyma wants to merge 10 commits into
Conversation
…erver OOM when enabling Netty
…erver OOM when enabling Netty
…erver OOM when enabling Netty
6b8c440 to
dc50ca4
Compare
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #1519 +/- ##
============================================
+ Coverage 54.27% 54.57% +0.30%
+ Complexity 2807 2791 -16
============================================
Files 427 410 -17
Lines 24349 22123 -2226
Branches 2077 2100 +23
============================================
- Hits 13215 12074 -1141
+ Misses 10305 9290 -1015
+ Partials 829 759 -70 ☔ View full report in Codecov by Sentry. |
Test Results2 042 files - 245 2 042 suites - 245 2h 20m 15s ⏱️ - 2h 9m 28s For more details on these errors, see this check. Results for commit d890a53. ± Comparison against base commit 3954ce7. This pull request removes 73 and adds 7 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
|
Maybe we can spit this pull requests to some smaller pull requests. It will be easier to review. Surely, it's good to summit a drat pull request at request to give reviewers an overall view. |
Smaller pull requests will be:
Maybe 1 and 5 can be in one pull request too? WDYT? @jerqi |
1 and 2 can be one pull request, too. Five pull requests seems easier to review. |
|
I'll initially submit these three pull requests, and the remaining ones can be submitted once these are merged. |
…Memory and usedDirectMemory (#1524) ### What changes were proposed in this pull request? We need to know the exact direct memory usage of `PooledByteBufAllocator` in `Netty`. So we should introduce metrics for Netty's `pinnedDirectMemory` and `usedDirectMemory`. ### Why are the changes needed? A sub PR for: #1519 ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? Existing UTs.
…ption issues in extremely rare scenarios (#1522) ### What changes were proposed in this pull request? Improve the robustness of methods `ShuffleDataResult.release()` and `ShuffleIndexResult.release()` to fix occasional IllegalReferenceCountException issues in extremely rare scenarios. ### Why are the changes needed? A sub PR for: #1519 ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? Existing UTs.
…ks instead of reallocating it (#1521) ### What changes were proposed in this pull request? Reuse ByteBuf when decoding shuffle blocks instead of reallocating it ### Why are the changes needed? A sub PR for: #1519 ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? Existing UTs.
|
I still don't understand the reason of OOM for this. Could you help explain why the usedMemory can't reflect the real memory used compared with grpc based server? @rickyma |
As described in this PR previously, Netty allocates direct memory by pages and chunks.
When the concurrent pressure of the shuffle server is not high, the I don't know if it is clear to you now. |
Who will release and flush |
I mean |
Got you point, so you suspect the bytebuf occupied memory size is not equals to the real used size, right? How about initializing the bytebuf with capacity like: |
You can't precisely control the size of the |
If so, why not creating a new fixed size bytebuf to fill above composite bytebuf? And the overhead memory occupied exceeded can be reflected to the client side using backpressure? |
As I mentioned above, you cannot control the size of the
And it will cause the issue that I mentioned in #1521-comment. |
I think backpressure can be implemented in another PR, which would be a further improvement to this issue. The current PR is meant to address the problem of inaccurate |
…mory issue causing OOM (#1534) ### What changes were proposed in this pull request? When we use `UnpooledByteBufAllocator` to allocate off-heap `ByteBuf`, Netty directly requests off-heap memory from the operating system instead of allocating it according to `pageSize` and `chunkSize`. This way, we can obtain the exact `ByteBuf` size during the pre-allocation of memory, avoiding distortion of metrics such as `usedMemory`. Moreover, we have restored the code submission of the PR [#1521](#1521). We ensure that there is sufficient direct memory for the Netty server during decoding `sendShuffleDataRequest` by taking into account the `encodedLength` of `ByteBuf` in advance during the pre-allocation of memory, thus avoiding OOM during decoding `sendShuffleDataRequest`. Since we are not using `PooledByteBufAllocator`, the PR [#1524](#1524) is no longer needed. ### Why are the changes needed? A sub PR for: #1519 ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? Existing UTs.
### What changes were proposed in this pull request? Fix [#1008](#1008). It does not actually test `GRPC_NETTY` mode, because it uses `ShuffleServerGrpcClient` everywhere instead of `ShuffleServerGrpcNettyClient`. Setting the shuffle server's tags to `GRPC_NETTY,GRPC` is useless, because we are not using `ShuffleServerGrpcNettyClient` at all. ### Why are the changes needed? It is a sub PR for: #1519 Also, it is a follow-up PR for: #1008 ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? Existing UTs.

What changes were proposed in this pull request?
When the shuffle server enables Netty, during the pre-allocation of memory and flushing buffer, we should use the actual used direct memory(which is pinnedDirectMemory in
PooledByteBufAllocator) andmaxDirectMemoryfor the if statement, instead of the previoususedMemoryandcapacitydue to #1472.Changes:
usedMemorymetric.ByteBufinDecoders.decodeShuffleBlockInfo(), we can reuse it usingreadSlice.allocated_direct_memory_sizeandpinned_direct_memory_size. Refer to Add pinnedHeap/DirectMemory methods to ByteBufAllocatorMetric netty/netty#11667.ShuffleDataResult.release()andShuffleIndexResult.release()to fix occasional IllegalReferenceCountException issues in extremely rare scenarios.GRPC_NETTYmode, because it usesShuffleServerGrpcClienteverywhere instead ofShuffleServerGrpcNettyClient. (I found this problem when fixing the previous UTs. Setting the shuffle server's tags toGRPC_NETTY,GRPCis useless, because we are not usingShuffleServerGrpcNettyClientat all.)Why are the changes needed?
For #1472
Detailed explanations:
The actual direct memory usage of a
ByteBufthat is going to be sent to a Netty server cannot be obtained in advance due to the dynamic nature of Netty's allocation and deallocation.We use a pooled
ByteBufAllocatorby default for performance reasons. When aByteBufis allocated, it is drawn from a pool of available memory, and when it is deallocated, it is returned to the pool. The size of theByteBufcan change dynamically as data is written to or read from it.Furthermore, the actual memory usage includes not only the capacity of the
ByteBuf, but also additional overhead for theByteBufobject itself and possibly other associated objects. This overhead is not constant and can vary depending on factors such as the JVM implementation, the specific Netty version, the runtime environment, and even the network.Therefore, it is generally not possible to accurately predict the actual direct memory usage of a
ByteBufin advance.While we were using it, we discovered that due to Netty's dynamic allocation of direct memory based on page and chunk sizes, the actual direct memory occupied by the shuffle server gradually deviates from
usedMemoryover time. Consequently, it fails to meet the flush conditions for an extended period, as flushing or not relies onusedMemory. This results in direct used memory exceeding its limit, which explains why an out-of-direct-memory error is prone to occur under high-pressure and high-concurrency situations. If the pressure is insufficient, the job might be completed before this issue arises.Does this PR introduce any user-facing change?
GRPC_NETTYmode,usedMemorywill usepinnedDirectMemory.rss.server.netty.directMemoryTracker.memoryUsage.updateMetricsIntervalMsandrss.server.netty.directMemoryTracker.memoryUsage.initialFetchDelayMsconfigurations are decreased to1s.How was this patch tested?
Fix #1008 to make it test
GRPC_NETTYmode usingShuffleServerGrpcNettyClient.We conducted stress tests in our production environment and the spark job ran successfully.
Before this PR, the spark job cannot run successfully.