mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #1887] [Feature Request & Discussion]: Group Semantics for Objects in Mooncake Store #537
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#537
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 @ykwd on GitHub (Apr 14, 2026).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/1887
Describe your feature request
Motivation
In many real-world scenarios, multiple objects stored in Mooncake Store actually represent different parts of a single logical entity.
Examples include:
We refer to such related objects as belonging to the same group.
Due to limitations in upper-layer engines:
put) by different processes.exists,get) by different processes.This can lead to inconsistencies and correctness issues.
Desired Behavior
We would like to introduce group-level semantics so that objects within the same group share consistent visibility and lifecycle behavior:
Group-aware existence checks
When calling
exists, users should not only know whether a single object exists, but also whether all objects in its group are present.getit.getdifferent tokens, it may lead to errors or inconsistencies.Group-level eviction
All objects in the same group should be evicted together, rather than independently.
Relation to Prefix-aware Eviction
This feature is closely related to prefix-aware eviction.
If prefix-aware eviction is implemented, it should also operate at the group level. For example:
Proposed Design (Discussion)
Introducing a group abstraction into the current interface and architecture is non-trivial. Below are some initial thoughts and open questions for discussion:
1. Forward Compatibility
Existing APIs should continue to work unchanged.
The system should support cases where no group is specified.
Possible approaches:
2. API Changes
Since objects in the same group may be uploaded by different processes, we need a way to determine whether a group is complete.
We propose extending the
putinterface to include group metadata:group_id: identifier of the groupgroup_size: total number of objects in the groupgroup_index: index of the current object within the groupExample (8-way pipeline parallelism):
(tokenA_0, group=tokenA, index=0/8)(tokenA_1, group=tokenA, index=1/8)This allows the system to determine when all objects in a group are present.
3. Design Considerations
a. Sharding Strategy
Should all objects in a group reside in the same shard?
If distributed across shards:
b. Metadata Design
c. SSD Offloading Compatibility (Optional)
d. Compatibility with Existing
removeAPIHow should
removebehave with grouped objects?e. Fault Tolerance
Group semantics introduce additional failure modes:
putoperation starts but never completes?These cases require careful handling, similar to (but more complex than) current per-object fault tolerance.
How to Contribute
This feature is relatively complex and touches multiple parts of the system.
We would like to first align on the design and approach through discussion before moving to implementation.
Contributions are very welcome! In particular:
Thanks in advance for your thoughts and discussion 🙌
Before submitting a new issue...
@CAICAIIs commented on GitHub (Apr 24, 2026):
This is a very interesting design problem. I’d be happy to work on this issue.
From the discussion so far, my current understanding is that the main design fork is whether we want
exists, whilegetremains per-object, orI think that decision affects a few follow-up questions
Curious which direction is preferred here, since it seems to define the boundary of the feature.
@huangtingwei9988 commented on GitHub (Apr 29, 2026):
A really nice design! once the functionality is implemented, I'll be using it in sglang right away.
@Colors-111 commented on GitHub (Apr 29, 2026):
The group semantics described in this issue seem to naturally correspond to the RadixTreeNode design proposed in the Radix Tree RFC (#1998 ). The key insight is that the prefix hash already provides the group boundary:
Different model configurations use different key formats:
But the first 64 characters are always a blake3 hex digest identifying a RadixAttention node.
This naturally partitions objects into groups (nodes) — each prefix_hash corresponds to one group, and all objects sharing that prefix are its members. The Radix Tree design already treats each node as a unit for both registration and eviction (leaf-level atomicity). The one gap is group_size: the current design doesn't store the expected number of keys per node, so we can't distinguish "partially uploaded" from "partially evicted." Adding an expected_key_count field to RadixTreeNode would close this gap — the inference framework provides the value since it knows the PP/TP topology.
@Srinivasoo7 commented on GitHub (May 1, 2026):
@Colors-111 that makes sense. After reading RFC #1732 and the newer Radix Tree RFC #1998, I think the group boundary for this issue may already be naturally defined by the RadixTreeNode.
My understanding is:
So I believe the remaining unresolved piece is not “how do we define a group?” but “how do we know whether the group/node is complete?”
Currently RadixTreeNode has registered_keys, but it does not appear to store the expected number of keys for that node. Because of that, we cannot distinguish:
Curious to understand would adding something like expected_key_count to RadixTreeNode be a reasonable minimal extension?
For example:
This seems to avoid introducing a separate generic group_id/group_size/group_index abstraction for the RadixAttention use case, while still solving the visibility/completeness issue described here
The remaining design question would be failure handling: if a writer crashes and the node never reaches expected_key_count, should the incomplete node stay invisible until TTL/GC removes it, or should it be explicitly marked incomplete/in-flight?
@CAICAIIs commented on GitHub (May 9, 2026):
I’d like to propose a phased implementation plan for this issue.
My current understanding is that the core problem is group completeness and group-level lifecycle consistency, rather than a full prefix/radix-tree implementation in the first PR.
Proposed PR breakdown
PR 1: Group metadata and group-aware exists
group_idexpected_member_countgroup_indexPutStartcleanup so incomplete groups do not become visible as complete.PR 2: Group-level eviction
PR 3: Lifecycle and integration follow-ups
prefix_hashtogroup_id, with the inference framework providingexpected_member_count.This keeps the first PR focused on the minimal correctness primitive: group completeness. It also avoids depending on a full Radix Tree design before that direction is finalized.
Would it be okay for me to work on this issue?
@stmatengss commented on GitHub (May 9, 2026):
@zxpdemonio PTAL.
@ykwd commented on GitHub (May 19, 2026):
@CAICAIIs Sorry for the late reply. I think the solution you proposed is very detailed, and the various issues were considered quite thoroughly.
However, @yokinoshitayoki later ran some benchmarks and found that, when the global memory pool becomes large enough, the probability that only part of the objects in a group are evicted while others remain is actually quite low. At the same time, considering that network communication in distributed systems can always fail, guaranteeing that all objects in a group can always be fetched together would require substantial changes — including major modifications on the SGLang/vLLM side as well.
Taking everything into account, we proposed a best-effort strategy instead, aiming to support group semantics with minimal changes: https://github.com/kvcache-ai/Mooncake/issues/2127
I think we can collaborate with @yokinoshitayoki on this feature.