LLM Infer Infra 学习资料库

LMCache:存储后端契约与 Mooncake 接入

白话导读:讲清 LMCache 对存储后端的要求,以及接上 Mooncake 时两边各负责什么。

  • 推理 KV 存储比普通 KV 存储多了四个要求:前缀依赖、张量布局、分片完整性、设备生命周期。
  • Mooncake 分三层看:Transfer Engine 搬字节,Store 管对象和租约,上层集成把前缀语义接到推理调度。
  • RDMA 模式要求 L1 内存预先注册,配置不对会直接报错,不会悄悄退回 TCP。

通用的存储原理以KV 存储详解为准;本篇重点是 LMCache 对后端的接口要求。完整的保存与恢复链路见联合链路。

1. 推理 KV 存储和普通 KV 存储哪里不一样

一句话:普通 key-value 服务只关心“存进去的值能不能正确读出来、快不快”;推理 KV 缓存还要关心四件事:前缀依赖、张量布局、分片是否完整、设备上的数据什么时候算完成。

它的数据特点也很不一样:对象很大,访问有很强的前缀和会话局部性,数据丢了可以重算,但用错了绝对不行。存储层可以不懂注意力,但集成层(例如 LMCache)必须把这些语义变成清楚的接口约定。

举个量级:一个 256 token 的 chunk 可能有几十 MiB,而且同一个逻辑 chunk 会拆成多个 rank、多个组的对象。所以 Redis 那种“每秒多少次小对象操作”的指标说明不了问题,要看的是大对象带宽、批量开销、内存拷贝次数、查找放大和尾延迟。

2. 数据放哪一层

层级好处代价与风险适合放什么
GPU 显存 / APC注意力可以直接用贵,和权重、运行时抢显存最近用过、马上要 Decode 的 KV
本机内存容量较大,不走网络H2D/D2H 拷贝、NUMA、锁页、挤占 CPU 内存多轮对话、同一台机器上不同引擎之间复用
远端内存多台机器的内存合成一个池子,可跨节点共享网络、控制服务、故障和热点共享文档、长上下文、弹性扩缩的计算池
本地 NVMe / 文件容量便宜IOPS、吞吐、写放大、文件元数据、page cache 干扰次热数据、重启后复用
共享文件 / 对象存储容量大、可跨节点、可选持久化往返延迟、请求费用、吞吐和恢复流量长尾缓存、预热、能接受较慢加载的场景

“远端”不一定比“磁盘”慢,“本地”也不一定最快;实际速度由对象大小、排队、介质、拓扑和软件路径共同决定,不要给各层排一个固定的快慢名次。另外,L2 可以配置多个 adapter,但默认策略不会自动学习哪层最快。

3. 三类策略要分开设计

讨论时可以用“价值密度”来衡量一个对象值不值得留:

V i = P i ( reuse ) ⋅ ( T i ( recompute ) − T i ( load ) ) bytes i

意思是:被复用的概率 × 每次复用能省下的时间,再除以占用的字节数。这是讨论用的启发式模型,不是 LMCache 的默认算法,实际还要扣掉写入流量、复制成本和占用空间的机会成本。另外,前缀依赖意味着单独留下的后缀 chunk 即使还在也用不上,淘汰策略应该看“有效前缀”,而不只看对象被访问了几次。

写入时机也是三种不同策略:同步写穿(write-through)、异步后写(write-behind)、淘汰时才写回(write-back)。缓存可以丢弃能重算的数据,不代表写路径都要做数据库级别的事务;但调用方必须知道“存储完成”到底是哪一层完成了。

4. Mooncake 分三层看

  1. Transfer Engine:在已注册的地址之间搬字节,提供 segment、批量传输、多种传输协议和完成状态。它不判断一段 KV 能不能给某个 prompt 用。
  2. Mooncake Store:管理“key → 对象和副本在哪”、空间分配、生命周期、租约和存储池。客户端通过 Transfer Engine 直接读写数据。
  3. 上层集成与路由:LMCache、SGLang HiCache、vLLM connector 或 Conductor 把前缀身份、对象命中和实例位置接到推理调度上。

Mooncake 论文里描述的是一整套以 KV 为中心的服务方案,不能和“装了 Transfer Engine 库的应用”画等号。仓库里还有 PG/EP、Reshard 等组件;KV 存储岗位先掌握 Store 和 Transfer Engine,MoE 通信可以作为后续专项。

5. Store 的读写与一致性边界

普通 Put 和 Get 的概念流程:

写者 → Master:PutStart,申请空间和副本位置
写者 → 目标 segment:通过 Transfer Engine 写数据
写者 → Master:PutEnd,报告写完
读者 → Master:GetReplicaList,拿到可读副本和读保护(租约)
读者 ← 目标 segment:直接读数据

Master 不转发大块数据。Master 不可用会挡住新的查找和分配,但原因不是“所有字节都要经过 Master 的网卡”。另外,Transfer Engine 的元数据(segment 怎么访问)和 Store Master 的对象目录(对象在哪、能不能读)也是两回事。

普通 Put 按“不可变对象”设计;学习版本里也有 Upsert,所以不要说“Mooncake 永远不能改值”。但对按内容寻址的 KV 复用,应该用清楚的模型版本和对象身份,不要覆盖旧 key,否则正在读的人可能读到另一个版本。

下面五个概念经常被混:

概念解决什么不能保证什么
读租约一段时间内保护正在读的副本不被淘汰或删除不是对象的固定存活时间;读太久超过租约就可能失败
soft pin影响淘汰优先级或是否允许淘汰不是永不丢失;学习版本中读操作不会延长它
副本提高容错和热点读带宽会增加容量和写流量;实际拿到几个副本要确认
持久化满足介质和完成协议时数据不丢全内存多副本挡不住整个集群断电
Master 高可用主节点故障后能切换需要真正部署选主和恢复;只跑一个 Master 进程不会自动高可用

对一组相关对象,Mooncake 可以提供共享租约和尽力而为的生命周期处理,但这不等于推理引擎层面“所有 TP rank 和组都完整”的判断,也不是任意多对象的事务。

以上依据 Mooncake 的 docs/source/design/store/mooncake-store.md、docs/source/design/architecture.md 和 docs/source/api-reference/python/mooncake-store.md。Store 内部实现见 Mooncake 内核与源码。

6. LMCache 接 Mooncake 时谁管什么

学习版本的 MP 模式通过 mooncake_store native L2 adapter 接入 Mooncake。Python 入口是 lmcache/v1/distributed/l2_adapters/mooncake_store_l2_adapter.py,C++ 后端在 csrc/storage_backends/mooncake/。不要把它和旧的进程内 remote connector 的 YAML 配置混用。

谁负责什么
LMCache引擎侧语义:chunk、组、key、L1 buffer、预取与保存任务、设备完成
native adapter把 L2 请求翻译成 Mooncake 操作,管理异步任务和线程池
Mooncake Store对象位置、副本、segment 空间、读写保护和对象生命周期
Transfer Engine在可访问的 buffer 之间搬字节,报告真实的完成或失败
部署的人模型、分片、布局一致;租户授权;容量、拓扑、二进制兼容和服务可达

配置怎么分:type、num_workers、per_op_workers、eviction 由 LMCache 自己用,其余字段原样以字符串传给 Mooncake 的 setup_internal(ConfigDict)。LMCache 不会替你补齐 Mooncake 需要的参数。线程池可以按 lookup/retrieve/store/delete 分开,避免大量写入堵住查询;但线程多不等于带宽高。

RDMA 模式:要求提供有效的连续 L1 内存描述,缺了会直接报错,不会悄悄退回 TCP。文档建议加 --no-l1-use-lazy,让 L1 在注册前就分配好。常见数据路径是 GPU ↔ LMCache 主机 L1 ↔ 远端 segment;即使 Store 本身支持设备内存,也不能说这条集成路径自动省掉了 H2D/D2H。

构建:装了 Mooncake 的 Python 包,不代表 LMCache 的 C++ Mooncake 扩展已经编好;后者要单独设置 BUILD_MOONCAKE=1,并准备头文件和库。完整配置见 Mooncake adapter 指南,实验步骤见LMCache 实验。

7. RDMA 面试要说清的几点

常见硬件的公开带宽和延迟量级见实测与故障演练:公开参考数据。

8. 和其他组件怎么对比

组件主要做什么和 LMCache / Mooncake 的关系
vLLM APC引擎内 GPU 前缀复用和 LMCache 互补;做实验时别把 APC 的收益算到外部缓存头上
SGLang RadixCache / HiCache前缀树索引和分层 KV 管理可以接 Mooncake Store;不同路径不要无规划地重复卸载同一份数据
LMCache跨引擎集成、KV 生命周期和分层复用可以把 Mooncake Store 当 L2;它不替代推理引擎
Mooncake Store分布式对象池和生命周期可以服务 LMCache 或其他上层缓存
Mooncake Transfer Engine按地址和 segment 搬数据可以直接用于 PD 交接,也是 Store 的数据通道;它不是 Store
NIXL可插拔的数据传输抽象和后端可用于 PD 或 LMCache 的部分 L2 路径;本身不提供前缀缓存语义
缓存感知路由 / Conductor / Coordinator根据命中位置做路由或协调索引可能过时,实际加载时必须再验证;不应该成为数据中转站

层号命名不统一:SGLang HiCache 常把 GPU 叫 L1、主机内存叫 L2、外部存储叫 L3;LMCache MP 常把主机内存叫 L1、后端叫 L2。面试时先说物理介质,再说层号,免得两边说的“L2”根本不是同一个地方。

9. 延伸阅读

输入主题、术语或问题