mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #3052] [Bug]: client 重启后, ssd 上的数据全部失效 #781
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#781
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 @sun-baoshan-sunshine on GitHub (Jul 22, 2026).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/3052
Bug Report
mooncake version: v0.3.11.post1
1. Background
When a client with SSD offload enabled crashes unexpectedly and is subsequently restarted in a short timeframe, the SSD data previously held by the client becomes stale/invalid, rendering it inaccessible.
2. Analysis
Under normal circumstances, upon restart, the client is expected to scan the data residing on the SSD and report the metadata to the Master via ScanMeta. However, if the new client's registration/reporting occurs within the TTL (Time-To-Live) window of the previous client instance — meaning the old client has not yet been evicted by the Master — the new client's registration attempt is effectively a no-op and is rejected. The root cause of this issue resides in the logic of auto MasterService::AddReplica(const UUID& client_id, const std::string& key, Replica& replica).
When the new client reports its keys, since the old client has not yet expired, those keys already exist in the Master's metadata. During the check for whether a disk replica exists for the keys reported by the new client, there is no validation to verify whether the client_id matches the one associated with the existing metadata entry. As a result, the Master incorrectly concludes that the data reported by the new client is already present and takes no further action.
Subsequently, when the old client reaches its TTL and is evicted by the Master, its corresponding metadata is also purged. Consequently, the KV cache data residing on the SSD becomes orphaned and can no longer be accessed or served.
Before submitting...
@github-actions[bot] commented on GitHub (Jul 22, 2026):
Thanks for opening this issue, @sun-baoshan-sunshine!
78401405A maintainer will triage this when possible. To help us respond faster, please include:
Useful links: Documentation · Contributing guide
@he-yufeng commented on GitHub (Jul 22, 2026):
Confirmed this chain on current main (
12df58c7):ReRegisterOffloadedObjects, which scans the SSD and reports every object throughNotifyOffloadSuccess(file_storage.cpp:1216stampstransport_endpointwith the currentlocal_rpc_addr_).MasterService::AddReplica(master_service.cpp:3344),HasReplica(fn_is_local_disk_replica)is true because the dead incarnation's replica is still registered. TheVisitReplicasupdate path only matches a replica whoseclient_idequals the reporting one, so the restarted client's report matches nothing and is silently dropped.AddReplicareturns false and the caller treats the batch as fine.ClientMonitorFunc->ClearInvalidHandles->CleanupStaleHandlesremoves completed local_disk replicas whose owner is not alive, and the object is erased when no valid replica remains. The files stay on the SSD but the master no longer knows they exist.One wrinkle for the fix:
master_service_tenant_quota_test.cpp:480(NotifyOffloadSuccessDoesNotCountAddReplicaUpdateAsNewDiskUsage) pins the current drop as intended behavior for the two-live-clients case: client B re-reporting the same key gets deduped and is not charged usage. So "just append the second replica" contradicts a tested design decision.A direction that keeps that test green: treat the report as an ownership takeover only when the existing disk replica's
transport_endpointequals the reporter's endpoint. A restarted client re-scans and reports the samelocal_rpc_addr_its dead incarnation registered with, so the master can retarget the replica to the newclient_idand charge the usage there. A genuinely different client reports a different endpoint and still lands in the dedup path. The caveat is that this only works whenlocal_rpc_addr_is stable across restarts (fixed RPC port, not ephemeral). Is that true in your deployment?Happy to send the PR if this direction sounds reasonable to @ykwd and @staryxchen.
@LujhCoconut commented on GitHub (Jul 23, 2026):
@he-yufeng Sounds right. This makes sense to me. The
ransport_endpointmatch is the proper discriminator here. Happy to review when the PR is up.@sun-baoshan-sunshine commented on GitHub (Jul 24, 2026):
@he-yufeng @LujhCoconut Has it been confirmed that a pr will be submitted to resolve this issue?
@LujhCoconut commented on GitHub (Jul 24, 2026):
@sun-baoshan-sunshine There will definitely be a PR to fix this issue. If you or @he-yufeng are willing to submit a PR, I'd be happy to review it. Alternatively, I can also submit a PR to address this.
@github-actions[bot] commented on GitHub (Oct 22, 2026):
This issue has had no activity for 90 days and will be closed in 7 days if there is no further activity. Please comment or react if it should stay open.
@github-actions[bot] commented on GitHub (Oct 29, 2026):
Closing due to 3 months of inactivity. If this is still relevant, please comment and we can reopen.