Prhub

#22592 [BugFix][RadixTree]:Fix stale eviction assertion in HiMambaRadixCache host eviction path

原始 PR 作者 icepoint666 合并时间 2026-04-16 10:49 文件变更 1 提交数 3 评论 20 代码增减 +1 / -4

执行摘要

修复 HiMambaRadixCache 过期淘汰节点断言崩溃

当使用 --enable-hierarchical-cache 且 Mooncake 后端在高并发场景下运行时, HiMambaRadixCache 会在 _delete_tombstone_leaf() 中抛出 AssertionError: parent does not have child key。 原因是 write_backup() 可能在 radix 树仍被 insert/split 逻辑更新时触发 evict_host(), 驱逐候选集中的节点引用已过期。

值得快速合入, 但需要关注后续 PR #23696 的进展, 以及用户反馈的剩余问题。建议精读 hi_mamba_radix_cache.py 中的驱逐逻辑设计。

讨论亮点

reviewer gemini-code-assist[bot] 提出两个改进建议:① 在 _evict_regular 中应将过期节点检查放在断言之前, 以避免断言先失败;② _cleanup_stale_node 中 LRU 列表移除应更无条件, 确保 tombstone 节点也被清理。但这两个建议对应的代码实际上不在最终合并的变更中(PR 只修改了 _update_full_host_leaf_status)。 最终 reviewer hzh0425 批准了 PR。

在 issue 评论中, 用户 riZZZhik 反馈此修复后断言频率大幅降低但仍有发生, 作者 icepoint666 建议尝试关联 PR #23696 以彻底解决。

实现拆解

  1. hi_mamba_radix_cache.py_update_full_host_leaf_status 方法中, 增加 len(node.children) > 0 条件,当节点仍有子节点时直接将其从 evictable_full_host_leaves 集合中移除并返回。
  2. 删除原有的子节点遍历逻辑(检查所有子节点是否 evictedbackuped), 因为新条件更严格且更高效:有子节点的节点不是叶子节点,不应被驱逐。
  3. 该修改仅涉及 +1/-4 行代码,是一个最小化修复,不改变驱逐策略本身。
文件 模块 状态 重要度
python/sglang/srt/mem_cache/hi_mamba_radix_cache.py 缓存层 modified 5.22

关键符号

_update_full_host_leaf_status

关键源码片段

python/sglang/srt/mem_cache/hi_mamba_radix_cache.py core-logic

唯一的变更文件,修改了 `_update_full_host_leaf_status` 方法,增加 `len(node.children) > 0` 检查,防止非叶子节点被加入驱逐候选集。

def _update_full_host_leaf_status(self, node: TreeNode):
    # 如果节点已 evicted、已 backuped、不是根节点、 引用计数都为 0 且没有子节点(即真正的叶子节点),
    # 才将其加入 evictable_full_host_leaves 集合。 否则从集合中移除。
    if (
        not node.evicted
        or not node.backuped
        or node == self.root_node
        or node.host_ref_counter > 0
        or node.host_mamba_ref_counter > 0
        or len(node.children) > 0 # [ 修复 ] 有子节点的节点不是叶子, 不应被驱逐
    ):
        self.evictable_full_host_leaves.discard(node)
        return
    # 原有的子节点遍历检查被移除: 如果节点有子节点, 上面的条件已覆盖
    self.evictable_full_host_leaves.add(node)# 注: 原本的 for 循环检查所有子节点是否 evicted && backuped 的逻辑已被删除,
# 因为新的条件更严格: 任何子节点的存在都意味着非叶子, 不应驱逐。

评论区精华

过期节点检查位置 正确性

reviewer 建议在 `_evict_regular` 中将过期节点检查放在断言之前,避免断言先失败

结论:该建议对应的是未合入的扩展代码,最终 PR 只修改了 `_update_full_host_leaf_status`,不涉及此问题 · 已解决

LRU 列表清理健壮性 正确性

reviewer 指出 `_cleanup_stale_node` 可能因条件检查跳过 tombstone 节点的 LRU 清理

结论:该建议对应的是未合入的扩展代码,最终 PR 不包含 `_cleanup_stale_node` 方法 · 已解决

修复效果反馈 other

用户 riZZZhik 反馈修复后断言大幅减少但仍偶发,作者建议尝试关联 PR #23696

结论:问题未彻底解决,需要结合后续修复 · unresolved

风险与影响

风险较低。变更仅在一个私有方法 _update_full_host_leaf_status 中增加了前置检查并删除了循环遍历, 不会影响正常驱逐路径。但用户报告说在高负载下仍有类似断言, 说明该问题可能未被完全解决,需要结合 PR #23696 进一步修复。

影响范围仅限于启用 --enable-hierarchical-cache 且后端为 Mooncake 的高并发场景。 修复后避免了调度器崩溃, 提高了系统的鲁棒性。对未启用 Hierarchical Cache 的用户无影响。

竞态条件修复 用户反馈未完全解决

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论