Prhub

#45206 [Bugfix][KVConnector][Mooncake] Close MooncakeDistributedStore on connector teardown

原始 PR 作者 Dao007forever 合并时间 2026-06-12 05:33 文件变更 4 提交数 1 评论 4 代码增减 +125 / -0

执行摘要

关闭 MooncakeDistributedStore 句柄在连接器拆卸时的泄漏

MooncakeStoreConnector never overrode the base KVConnectorBase_V1.shutdown() hook and had no del, so the worker's MooncakeDistributedStore handle was never closed officially (we depend on aexit on C++ side to clean up). The store owns a TransferEngine, the registered RDMA buffers, and the connection to the master server — all of which leaked on every connector teardown (e.g. engine shutdown, and RL/serving workflows that recreate the connector).

建议阅读。该 PR 修复了一个实际资源泄漏,设计上采用了幂等关闭、异常抑制和 GC 兜底等最佳实践,代码简洁清晰,测试覆盖完整,值得学习和复用。

讨论亮点

在 review 中,stmatengss 询问 shutdown() 中为什么不直接使用 try-except 保护 worker.close()。Dao007forever 回应 worker.close() 内部已经在 store.close() 处捕获异常,外部无需重复。stmatengss 理解并同意,最终 LGTM。

实现拆解

  1. MooncakeStoreWorker 添加 close() 方法(文件: worker.py):新增 close() 方法,通过 store.close() 释放 MooncakeDistributedStore 句柄。方法先置空 self.store 以保证幂等,并用 try-except 抑制异常,仅记录警告。
  2. MooncakeStoreConnector 添加 shutdown() 和 del()(文件: connector.py):覆盖基类的 shutdown() 钩子,调用 worker.close() 释放资源;对 SCHEDULER 角色(无 worker)为安全无操作。同时添加 __del__() 作为 GC 兜底,调用 self.shutdown(),与 Nixl 连接器模式一致。
  3. 新增单元测试(文件: test_mooncake_store_worker.pytest_mooncake_store_connector.py):使用 MagicMock 模拟 store,覆盖 close 的释放、幂等、异常吞噬,以及 connector 的 shutdown、del 和调度器角色空操作。
文件 模块 状态 重要度
vllm/distributed/kv_transfer/kv_connector/v1/mooncake/store/connector.py 连接器 modified 6.95
tests/v1/kv_connector/unit/test_mooncake_store_connector.py 连接器测试 modified 6.53
vllm/distributed/kv_transfer/kv_connector/v1/mooncake/store/worker.py 工作器 modified 6.46
tests/v1/kv_connector/unit/test_mooncake_store_worker.py 工作器测试 modified 5.89

关键符号

shutdown __del__ close

关键源码片段

vllm/distributed/kv_transfer/kv_connector/v1/mooncake/store/connector.py core-logic

核心变更文件,添加 shutdown() 和 __del__() 方法,覆盖基类钩子,确保连接器拆卸时释放 worker 的 store 句柄。

    def shutdown(self):
        """Release connector resources on teardown.
        Closes the worker's MooncakeDistributedStore handle so its
        TransferEngine and RDMA registrations are released."""
        # Get the worker instance; only WORKER role holds a store handle.
        worker = getattr(self, "connector_worker", None)
        if worker is not None:
            # worker.close() is idempotent and swallows exceptions.
            worker.close()
​
    def __del__(self):
        """GC backstop: ensures shutdown() is called even if the
        explicit teardown path is missed."""
        self.shutdown()

评论区精华

shutdown 异常处理设计 设计

stmatengss 询问 shutdown 中为什么不使用 try-except 包装 worker.close(),Dao007forever 解释 worker.close() 内部已在 store.close() 中捕获异常,故无需重复保护。stmatengss 理解并同意。

结论:保持现有设计,worker.close() 已处理异常。 · 已解决

风险与影响

本 PR 改动范围小,核心逻辑围绕资源释放,加入幂等和异常抑制设计,因此风险较低。潜在风险包括:

1) 若关闭后仍有其他组件引用 store 属性(已置空),可能引发 AttributeError,但 worker 内部已无后续使用;
2) 缺少端到端多节点 Mooncake 集群测试,硬件环境下的真实释放行为未验证;
3) 未同时关闭 LookupKeyServer 的 ZMQ socket 和 IPC 文件(PR 作者已注明作为后续跟进)。这些风险均可接受。

对用户:修复了一个资源泄漏 bug,提升长时间运行或频繁重新创建连接器的场景(如 RL/serving 工作流)的稳定性。对系统:每个连接器拆卸时不再泄漏 TransferEngine 和 RDMA 缓冲区,减少内存压力。对团队:提供了一种标准的连接器资源拆卸模式(shutdown + __del__ + 幂等 close),可供其他连接器(如 Nixl)参考。测试覆盖完善,无需 GPU 即可验证逻辑。

幂等安全 异常抑制

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论