mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #3909] [Performance]: Segmentation fault in asio epoll_reactor when frequently recreating read-only RealClient under extreme network timeout #1002
Labels
No labels
ascend
auto-closed
bug
bug
CI/Build
Common
documentation
enhancement
feature request
good first issue
help wanted
high priority
MetaX
nightly-failure
pull-request
PyTorch Backend
question
RFC
Roadmap
stale
Store
Tests
Transfer Engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/Mooncake#1002
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @waliwali777 on GitHub (Sep 7, 2026).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/3909
Describe your performance question
Overview
In large‑scale high‑throughput read‑only Mooncake workload, when simulating poor network with extremely short RPC timeout, tearing‑down and recreating read‑only RealClient after consecutive RPC timeouts triggers SIGSEGV null‑pointer crash. The service runs stable with normal MC_RPC_TIMEOUT_MS=400.
Hypothesis: Race between in‑flight coro‑rpc TCP async coroutine requests and client close / object destruction. According to coro_rpc doc, only send_request is thread‑safe; connect / close / object destruction must not run concurrently with unfinished RPC. Short timeout amplifies the race window. Resumed coroutine access already‑freed socket descriptor_data and causes segfault.
Deployment and Configuration
Cluster has 200 Mooncake storage nodes. Dataset is split into 200 partitions and fully persisted on local SSD without in‑memory read cache. Each storage node runs one
mooncake_masterplus one storage‑side RealClient; master only manages local RealClient. SSD offload & disk eviction enabled, promotion‑on‑hit disabled.Read‑side host with 8 GPUs, per rank process:
TransferEngineRealClientinstances, one‑to‑one connect to 200 remote storage nodes, read‑only workload,global_segment_size=0batch_get_intofor batch read. After 5 consecutive rpc_timeout failures: invoketearDownAll(), reset client object, later rebuild viasetup_internal.Per host scale: 8 ranks, total
200 * 8read‑only RealClient, high‑throughput random read pattern.Storage node: mooncake_master launch args
Storage‑side RealClient env & launch
Read‑only RealClient env
Key code snippet
Crash Backtrace
Crash occurs in TCP coro‑rpc path
BatchGetReplicaList. Direct cause:descriptor_data == nullptr, null‑pointer dereference inside asio epoll_reactor, SIGSEGV.Reproduction condition
MC_RPC_TIMEOUT_MS=20MC_RPC_TIMEOUT_MS=400Analysis & Questions
Reference coro_rpc doc:
https://github.com/alibaba/yalantinglibs/blob/main/website/docs/zh/coro_rpc/coro_rpc_client.md#%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8
Only partial APIs are thread‑safe for coro_rpc_client.
connect / close / object destructionmust not run concurrently with in‑flightsend_request.Race flow in our workload:
MC_RPC_TIMEOUT_MS=20, many RPC timeout rapidly.tearDownAll()and reset RealClient object.Questions:
RealClient(global_segment_size=0), should Mooncake add in‑flight request counter / guard to prevent destroying client with outstanding requests?Before submitting a new issue...
@github-actions[bot] commented on GitHub (Sep 7, 2026):
Thanks for opening this issue, @waliwali777!
51405922A maintainer will triage this when possible. To help us respond faster, please include:
Useful links: Documentation · Contributing guide
@he-yufeng commented on GitHub (Sep 8, 2026):
Taking this one. The mechanism chain on current main, read end to end:
RpcClientPool(mooncake-common/include/rpc_client_io_context.h), which hands out a sharedcoro_io::client_poolper master address and recreates it on address change.MasterClient::~MasterClient()is= defaultandRealClientteardown likewise never drains: the pool shared_ptr just drops whileco_await pool->send_request(...)coroutines can still be suspended (master_client.cpp:344/356/388/399).epoll_reactorsegfault you saw. ShortMC_RPC_TIMEOUT_MSwidens the window exactly as you described, since more requests are in flight at teardown.Fix shape I am implementing: an in-flight guard around the send_request path plus drain-on-destruct (stop admitting, wait bounded for in-flight to land, then release the pool), so teardown never frees state under a suspended coroutine. I will add a stress regression test that floods short-timeout reads while tearing down the client — red on current main, clean after.
@he-yufeng commented on GitHub (Sep 8, 2026):
PR #3943 is up. One honest correction to my plan note above: the stress harness did not reproduce your crash deterministically in-process (your 200-node timing window is much wider than a single-container loop), so the PR verifies by construction against ylt's documented thread-safety contract plus guard-semantics unit tests and a 16-in-flight teardown stress test that is green with the fix. While building it I also found that draining alone is insufficient: ylt's reconnect loop references pool storage across sleeps, which is why the PR also stops freeing pools (process-wide registry per address). If your environment still crashes on this branch, a stack from your side would pin whatever path mine missed.
@waliwali777 commented on GitHub (Sep 11, 2026):
Thanks a lot for your fix. I’ve added your PR and reran the test twice with an extremely short RPC timeout. So far I haven’t observed any core dumps. I will post more findings here if we see anything new in subsequent observations.