mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #2997] [Bug]: PutEnd silently discards PushOffloadingQueue failures — objects never reach the SSD tier, with no log or metric #774
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#774
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 @ccgibson on GitHub (Jul 20, 2026).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/2997
Summary
With eager offload (
enable_offload=1,offload_on_evict=0),MasterService::PutEndcallsPushOffloadingQueueand acts only on success. There is noelsebranch, no log, no metric, and no retry:An object whose enqueue fails therefore gets no offload task, is never written to the SSD tier, and dies RAM-only at the next memory eviction. Because it never had a disk replica, that eviction removes its last replica and the object leaves the pool entirely — a cache entry silently lost despite the SSD tier having free space.
Failure modes that can hit this
PushOffloadingQueue(master_service.cpp, ~L5150) can return:SEGMENT_NOT_FOUND— segment name not present in the local-diskclient_by_namemapUNABLE_OFFLOADING— no local disk segment for the resolved clientUNABLE_OFFLOADING—!enable_offloadingon that segmentKEYS_ULTRA_LIMIT—offloading_objects.size() >= offloading_queue_limit_OBJECT_ALREADY_EXISTS— key already present inoffloading_objectsNone of these are logged inside
PushOffloadingQueueeither, so the failure is invisible end-to-end.Why this is inconsistent
The eviction-path callers of the same function already count and log these failures, e.g.:
Only the
PutEndhot-path caller discards them. There is also no offload-related metric anywhere inmaster_metric_manager.{h,cpp}.Impact observed
In a production deployment we found roughly 9% of pool exits had no corresponding disk eviction — i.e. that fraction of objects left the cache without ever reaching SSD — while the SSD tier was well under its eviction watermark and the offload pipeline was healthy (multi-GB/s end-to-end store throughput, no queue backlog, no dropped events). With no log line and no counter anywhere, there was nothing to attribute it to; localising it required reading the source rather than any telemetry.
The measurement that surfaced it, for anyone hitting the same thing: compare cumulative pool exits against cumulative disk evictions. A persistent excess of the former means objects are leaving the cache without a disk replica.
Note this is distinct from #2632 / #2658 (offloading-task orphans causing 600s expiry warnings). That one produces a visible
Offloading task expiredwarning. This path produces nothing at all.Two additional silent-success paths
PushOffloadingQueuealso returns success ({}) while enqueuing nothing:if (segment_names.empty()) { return {}; }— early return before the loopsegment_nameslist whose entries are allnulloptfalls through the loop bodyIn both cases
PutEndsees success and records anOffloadingTask+inc_refcnt()for work that was never queued, so the task can only be cleared by the TTL expiry path.Suggested fix
At minimum, make the failure observable: add an
elseincrementing an offload-enqueue-failure counter and emitting a (sampled, since this is thePutEndhot path)WARNINGcarrying theErrorCode, mirroring what the eviction-path callers already do. That is enough to tell operators which failure mode dominates.Beyond that,
KEYS_ULTRA_LIMITandOBJECT_ALREADY_EXISTSarguably warrant retry or dedup handling rather than a dropped object, but making it visible seems like the necessary first step.Happy to open a PR for the observability part if that is a welcome direction.
Environment: observed on
v0.3.12-pre1; code path verified unchanged onmain@fc04cb1.@github-actions[bot] commented on GitHub (Jul 20, 2026):
Thanks for opening this issue, @ccgibson!
13460465A maintainer will triage this when possible. To help us respond faster, please include:
Useful links: Documentation · Contributing guide
@bestdo77 commented on GitHub (Jul 21, 2026):
Confirmed on main:
PutEndreturns success even whenPushOffloadingQueuefails (no local disk segment →SEGMENT_NOT_FOUND; full queue →KEYS_ULTRA_LIMIT), with nothing logged or counted — the object silently loses its only chance to reach the SSD tier.I have a patch for the observability part ready: an
offload_enqueue_failedcounter inMasterMetricManagerplus a sampled warning (LOG_EVERY_N(WARNING, 100)) in thePutEndelse branch, mirroring what the eviction-path callers already do, with gtest coverage for both failure modes (all master suites pass, 179/179).@ccgibson you mentioned you'd be happy to PR this as well — since I already have it working, I'll go ahead and open the PR in a bit; very happy to take your review on it.
@github-actions[bot] commented on GitHub (Oct 20, 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 27, 2026):
Closing due to 3 months of inactivity. If this is still relevant, please comment and we can reopen.