# PR #39837 完整报告

- 仓库：`vllm-project/vllm`
- 标题：[KVConnector][LMCache] Propagate cache_salt through MP connector for per-user cache isolation
- 合并时间：2026-04-16 00:10
- 原文链接：http://prhub.com.cn/vllm-project/vllm/pull/39837

---

# 执行摘要

- 一句话：为 LMCache MP 连接器传播 cache_salt，支持按用户缓存隔离。
- 推荐动作：该 PR 值得精读，因为它展示了如何在分布式缓存系统中传播上下文信息以支持新功能（如按用户隔离）。关注点包括：数据流设计（从请求到跟踪器、元数据、适配器）、默认值处理（`or ""` 确保向后兼容）、以及与外部系统的接口协调。

# 功能与动机

根据 PR body 和关联 Issue LMCache/LMCache#3029，动机是支持 LMCache 的按用户缓存隔离功能。cache_salt 是 vLLM OpenAI API 中已有的每请求字段（用于前缀缓存隔离），需要将其传播到 LMCache MP 连接器，以便 LMCache 可以将其用于按用户存储配额。这是 vLLM 侧的对等变更，与 LMCache 仓库的接口扩展配合。

# 实现拆解

1. **在请求跟踪器中添加 cache_salt 字段**：在 `LMCacheMPRequestTracker` 类中添加 `cache_salt: str = ""` 字段，并在 `__init__` 方法中从 `request.cache_salt` 初始化（若为 None 则默认为空字符串）。
2. **在元数据中添加 cache_salt 字段**：在 `LMCacheMPRequestMetadata` 数据类中添加 `cache_salt: str = ""` 字段，并在 `GetStoreMetadata` 和 `GetRetrieveMetadata` 静态方法中从跟踪器复制该值。
3. **传播到调度器适配器**：在 `get_num_new_matched_tokens` 方法中，调用 `scheduler_adapter.maybe_submit_lookup_request` 时传递 `cache_salt` 参数。
4. **传播到工作者适配器**：在 `start_load_kv` 和 `wait_for_save` 方法中，收集 `cache_salts` 列表，并传递给 `worker_adapter.batched_submit_retrieve_requests` 和 `batched_submit_store_requests` 方法。
5. **测试与兼容性**：PR body 提到测试计划包括确保未设置 `cache_salt` 时行为不变（默认为空字符串），但未包含测试文件变更；集成测试将作为后续工作。

关键文件：
- `vllm/distributed/kv_transfer/kv_connector/v1/lmcache_mp_connector.py`（模块 KV 连接器；类别 source；类型 core-logic；符号 LMCacheMPRequestTracker, LMCacheMPRequestMetadata, GetStoreMetadata, GetRetrieveMetadata）: 这是唯一变更的文件，包含了 LMCache MP 连接器的核心逻辑，负责传播 cache_salt 以支持按用户缓存隔离。

关键符号：LMCacheMPRequestTracker.__init__, LMCacheMPRequestMetadata.GetStoreMetadata, LMCacheMPRequestMetadata.GetRetrieveMetadata, start_load_kv, wait_for_save, get_num_new_matched_tokens


## 关键源码片段

### `vllm/distributed/kv_transfer/kv_connector/v1/lmcache_mp_connector.py`

这是唯一变更的文件，包含了 LMCache MP 连接器的核心逻辑，负责传播 cache_salt 以支持按用户缓存隔离。

```python
@dataclass
class LMCacheMPRequestTracker:
    # ... 其他字段 ...
    cache_salt: str = ""  # 新增字段，用于存储缓存盐值，默认为空字符串

    def __init__(self, request: "Request"):
        self.request_id = request.request_id
        self.cache_salt: str = request.cache_salt or ""  # 从请求中提取cache_salt，若为None则默认为空字符串
        self.all_token_ids = request.all_token_ids
        # ... 其他初始化 ...

@dataclass
class LMCacheMPRequestMetadata:
    request_id: str
    direction: Literal["STORE", "RETRIEVE"]
    op: LoadStoreOp
    cache_salt: str = ""  # 新增字段，用于在元数据中传递缓存盐值

    @staticmethod
    def GetStoreMetadata(
        tracker: LMCacheMPRequestTracker,
        blocks_in_chunk: int,
        vllm_block_size: int,
    ) -> "LMCacheMPRequestMetadata | None":
        # ... 计算存储元数据的逻辑 ...
        if num_chunks >= 1:
            # ... 构建操作 ...
            ret = LMCacheMPRequestMetadata(
                request_id=tracker.request_id,
                direction="STORE",
                op=op,
                cache_salt=tracker.cache_salt,  # 从跟踪器复制cache_salt到元数据
            )
            # ... 更新跟踪器 ...
            return ret
        return None
    
    # GetRetrieveMetadata 方法类似，也包含 cache_salt=tracker.cache_salt
```

# 评论区精华

review 中主要讨论了代码一致性和潜在运行时错误：
- **gemini-code-assist[bot] 指出**：`cache_salt` 应在 `LMCacheMPRequestTracker` 数据类中显式声明为字段以保持一致性（已通过后续提交修复）。
- **gemini-code-assist[bot] 警告**：内部回退适配器方法（如 `batched_submit_retrieve_requests`）尚未更新以接受 `cache_salts` 参数，如果 `lmcache` 包未安装且使用回退，可能导致 `TypeError`。但此问题可能属于 LMCache 仓库的范畴，因为 PR body 提到适配器方法已接受 `cache_salt=""` 默认值（LMCache/LMCache#3029）。
- **ApostaC 批准**：简单表示“LGTM!”，表明变更整体被接受。

 - cache_salt 字段在数据类中的声明 (correctness): 通过后续提交添加了 cache_salt: str = "" 字段声明，问题已解决。
 - 内部回退适配器方法参数不匹配 (correctness): 根据关联 Issue，LMCache 侧已添加默认参数，因此风险较低，但需确保部署协调。

# 风险与影响

- 风险：技术风险较低，但需注意：
 1. **兼容性风险**：如果内部回退适配器未同步更新，当 `lmcache` 未安装时可能引发 `TypeError`。但根据关联 Issue，LMCache 侧已添加默认参数，因此风险可控。
 2. **回归风险**：变更核心是添加可选字段和参数，默认值为空字符串，因此当 `cache_salt` 未设置时行为应与之前一致，降低了回归可能性。
 3. **集成风险**：需要与 LMCache 仓库的变更（Issue #3029）协同部署，否则可能导致接口不匹配。
- 影响：影响范围有限：
- **用户影响**：对最终用户透明，除非通过 API 设置 `cache_salt`，否则无行为变化。为未来按用户缓存隔离功能奠定基础。
- **系统影响**：仅影响使用 LMCache MP 连接器的场景，涉及 KV 卸载和外部缓存路径。
- **团队影响**：需要与 LMCache 团队协调，确保接口变更同步。
- 风险标记：依赖外部系统协调 , 潜在接口不匹配

# 关联脉络

- PR #36644 [kv_offload+HMA][3/N]: Remove block_size from KVEvents: 同属 kv-connector 模块的 PR，涉及 KV 卸载事件系统的重构，与本 PR 的 LMCache MP 连接器变更相关。
- PR #39548 [Bugfix][Mooncake] Fix thread-local CUDA context for NVLink transfers in _send_blocks: 同属 kv-connector 模块的 PR，涉及 KV 传输的修复，展示了该模块的持续演进。