s0nskar opened a new pull request, #3696:
URL: https://github.com/apache/celeborn/pull/3696

   <!--
   Thanks for sending a pull request!  Here are some tips for you:
     - Make sure the PR title start w/ a JIRA ticket, e.g. '[CELEBORN-XXXX] 
Your PR title ...'.
     - Be sure to keep the PR description updated to reflect all changes.
     - Please write your PR title to summarize what this PR proposes.
     - If possible, provide a concise example to reproduce the issue for a 
faster review.
   -->
   
   ### What changes were proposed in this pull request?
   
   We are using 0.5.3 and noticed that after a worker processes a heavy shuffle 
workload, its Netty direct memory metric (usedDirectMemory) spikes to a high 
value and then gets stuck and never recovers — even after the all flush ends 
and the worker becomes completely idle. The memory stays stuck until the worker 
is restarted.
   
   <img width="1372" height="327" alt="Screenshot 2026-05-19 at 2 25 38 PM" 
src="https://github.com/user-attachments/assets/294ccb97-a1dc-4785-ad27-ecda36db0ed4";
 />
   
   Although i noticed that there are fixes which tries to handle this by using 
pinnedMemory – https://github.com/apache/celeborn/pull/3018 and 
https://github.com/apache/celeborn/pull/3099 but i think that this PR is the 
correct way to handle this instead of relying on pinnedMemory.
   
   ### Why are the changes needed?
   
   `PooledByteBufAllocator` maintains a per-thread `PoolThreadCache` for each 
Flusher thread. When a ByteBuf is released, instead of immediately returning 
its slot to the `PoolArena`, it goes into this thread-local cache. But the 
PoolArena's view of the underlying `PoolChunk` is not updated. 
`usedDirectMemory` counts all `PoolChunk` native memory regardless of how much 
is truly in use vs. sitting in thread caches.
   
   The thread cache is only swept when the owning thread crosses a allocation 
threshold, but since the worker is in pause state  after all flush items end, 
all flush thread gets blocked on workingQueue(index).take(). The cache is never 
swept, `PoolChunks` in thread cache are never freed, and usedDirectMemory stays 
frozen.
   
   In this PR, we are changing take() with poll() and on poll() timeout we are 
explicitly calling `allocator.trimCurrentThreadCache()` to flush cached 
`PoolChunks` back to the `PoolArena`, allowing fully-free chunks to be 
destroyed and usedDirectMemory to recover.
   
   A similar pattern is already used by:
   
   
https://github.com/apache/celeborn/blob/main/worker/src/main/java/org/apache/celeborn/service/deploy/worker/memory/ReadBufferDispatcher.java#L131
   
   ### Does this PR resolve a correctness bug?
   
   <!-- Check if yes. The `correctness` label will be added/removed 
automatically. -->
   - [ ] Yes
   
   ### Does this PR introduce _any_ user-facing change?
   
   <!-- Check if yes. -->
   - [ ] Yes
   
   
   ### How was this patch tested?
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to