Mooncake 仓库同时存在经典 Transfer Engine 和 TENT(Transfer Engine Next)。TENT 不是简单增加一种 Transport,而是重构了 Segment 生命周期、运行时调度、拓扑选择、QoS、故障转移和插件体系。

阅读版本:

Mooncake commit: 777cc7782417b6e554cf7c2d53210d0d8f89f5cc

一、为什么需要下一代引擎

经典 TE 已经支持 RDMA、TCP、NVLink 和多种硬件,但随着后端增加,TransferEngineImpl + MultiTransport + 各 Transport 容易出现几个问题:

  • Segment 生命周期分散在元数据和后端注册逻辑中;
  • 传输选择主要依赖静态协议与局部规则;
  • 多 rail、拥塞、故障和 QoS 难以统一调度;
  • 不同后端各自维护进度线程和资源模型;
  • 新硬件接入需要理解大量经典内部约定;
  • 请求取消、deadline 和 failover 缺少统一运行时。

TENT 将这些能力上移到 Runtime 层。

二、目录结构

TENT 核心位于:

tent/src/runtime/
├── transfer_engine_impl.cpp
├── segment.cpp
├── segment_manager.cpp
├── segment_registry.cpp
├── segment_tracker.cpp
├── transport_loader.cpp
├── transport_selector.cpp
├── progress_worker.cpp
├── admission_queue.cpp
├── qos_contract.cpp
├── receiver_credit.cpp
├── topology.cpp
├── control_plane.cpp
└── proxy_manager.cpp

外围包括:

metastore:etcd / redis / HTTP
rpc:控制面 RPC
platform:CPU/GPU 内存探测和分配
plugins:CUDA、ROCm 等平台插件
metrics:统一指标系统
transport:各传输插件

与经典 TE 相比,职责边界更加清晰。

三、兼容入口

公共 TransferEngine 仍然可以启用 TENT。src/transfer_engine.cpp 根据 use_tent_ 创建:

std::shared_ptr<mooncake::tent::TransferEngine>

经典参数会转换为 tent::Config

local_server_name -> local_segment_name
metadata connection -> metadata_type + metadata_servers

这层兼容降低迁移成本,但 TENT 自己的原生 API 和配置能表达更多调度语义。

四、SegmentManager 集中管理生命周期

经典模式中,Segment 信息分布在 TransferMetadata、注册表和各 Transport。TENT 引入:

Segment
SegmentManager
SegmentRegistry
SegmentTracker

可以把它们理解为:

  • Segment:本地或远端地址空间对象;
  • SegmentManager:创建、打开、注册和关闭 Segment;
  • SegmentRegistry:维护可查找对象和注册关系;
  • SegmentTracker:跟踪远端变化、引用和失效。

集中管理后,注销内存、远端重启、metadata 更新和正在执行的请求可以在同一生命周期模型中协调。

五、TransportLoader 与插件化

经典 MultiTransport::installTransport() 包含大量构建宏和 if (proto == ...) 分支。TENT 使用 TransportLoader 将后端加载与引擎核心解耦。

平台能力也通过 Device Plugin 扩展,例如 CUDA 和 ROCm 插件负责:

  • 识别设备内存;
  • 查询 device/NUMA 属性;
  • 提供平台特有注册或拷贝能力;
  • 向拓扑系统暴露设备关系。

这样新增硬件不必把所有条件编译逻辑堆进一个中心工厂。

六、TransportSelector

TENT 的 TransportSelector 不只按 Segment protocol 字符串路由,而是结合拓扑和运行期条件选择路径。

输入可以包括:

源、目标 memory type
源、目标节点和设备
拓扑距离
可用 transport
链路优先级
transport hint
当前 rail 状态

对应测试包括 topology priority matrix、transport hint、selector 等,说明选择逻辑被提升为可独立验证的模块。

理想决策可能是:

同 GPU / 同进程 -> 本地直接完成
同节点 GPU -> SHM / GPU IPC / NVLink
跨节点 GPU -> RDMA / EFA / UB
持久层 -> GDS / NVMe-oF
故障或不支持 -> TCP

七、ProgressWorker

TENT 用 ProgressWorker 统一推进异步操作。传统后端容易各自创建 poller,造成线程模型分散。

ProgressWorker 的职责类似事件循环:

取得待执行 operation
  -> 提交后端请求
  -> poll completion
  -> 推进多阶段 operation
  -> 处理 retry / cancel / timeout
  -> 完成用户 future/callback

测试覆盖 poll backoff 和 progress worker,意味着实现会在低延迟与空闲 CPU 消耗之间做权衡,而不是无限 busy polling。

八、AdmissionQueue 与 QoS

经典 TE 主要回答“怎样传”,TENT 进一步回答“现在是否应该传、谁先传”。

AdmissionQueueQoSContract 可以支持:

  • 带宽上限;
  • 请求优先级;
  • deadline;
  • 多租户公平性;
  • 大请求切片;
  • 拥塞时的 admission control;
  • deadline promotion。

仓库测试包含 bandwidth arbitration、deadline promotion 和 QoS contract。这说明 TENT 面向的不只是 microbenchmark 峰值带宽,而是共享 AI 集群中的可预测服务质量。

九、Receiver Credit

发送方很快并不代表接收方能无限承受请求。TENT 引入 receiver credit 管理接收端资源:

接收端公布 credit
  -> 发送端消费 credit 提交
  -> 请求完成后归还
  -> credit 不足则排队或限流

它可以避免接收端 staging buffer、队列或 RPC handler 被突发流量压垮。对需要双边协议或 remote stage 的后端尤其重要。

十、Remote Stage 与代理路径

并非所有源和目标都能直接建立单边访问。TENT 的 remote_stage_operationproxy_manager 支持分阶段路径:

源设备
  -> 本地或远端 staging
  -> 网络 transport
  -> 目标设备

虽然 staging 会增加一次拷贝,但它提供兼容性和故障回退。统一 operation 状态机可以把多阶段传输表现为一个用户请求。

十一、故障处理与取消

TENT 测试明显增加了:

failover
engine failover E2E
fault proxy
RDMA cancel
rail monitor
endpoint lifecycle
RPC handler isolation

这反映设计重点从“后端返回错误码”升级为:

  • 失败发生在哪个阶段;
  • 是否可以切换 rail 或 transport;
  • 已完成部分是否需要保留;
  • cancel 如何传播到底层;
  • callback 是否只触发一次;
  • shutdown 是否仍能安全回收资源。

十二、Metastore 与 Control Plane

TENT 把 metastore、RPC 和 control plane 明确分层:

Metastore:Segment 和节点描述
RPC:实时协商与命令
Control Plane:资源、拓扑、选择和故障协调
Data Plane:Transport 实际搬运

支持 etcd、Redis 和 HTTP,使集群部署可以按规模和依赖选择控制面。

十三、Metrics

TENT 有独立 metrics 模块和配置加载,测试覆盖指标记录和 HTTP server。值得观测的维度包括:

  • 请求数、字节数和吞吐;
  • queueing、submission 和 completion 延迟;
  • transport/rail 分布;
  • retry、failover 和 cancel;
  • receiver credit;
  • admission queue 深度;
  • deadline miss;
  • endpoint 与 Segment 生命周期。

对多路径引擎而言,没有这些指标就很难解释“为什么这次选了 TCP 而不是 RDMA”。

十四、经典 TE 与 TENT 对比

维度经典 TETENT
后端管理MultiTransport 中心工厂TransportLoader / 插件化
SegmentMetadata 与后端共同管理SegmentManager/Registry/Tracker
路径选择protocol 与固定优先级拓扑、hint、状态驱动
进度推进各后端自身 workerProgressWorker 统一运行时
QoS基础批次与负载信息AdmissionQueue + QoSContract
故障endpoint 级恢复rail、transport、operation 级 failover
接收控制后端自行处理Receiver Credit
可观测性分散统计统一 Metrics

十五、如何阅读和使用两代代码

如果目标是理解 Mooncake 当前广泛使用的数据路径,应先掌握经典 TE:

TransferEngineImpl
  -> TransferMetadata
  -> MultiTransport
  -> RDMA/TCP Transport

如果目标是开发新后端、QoS、容错或动态路由,应重点研究 TENT:

SegmentManager
  -> TransportSelector
  -> AdmissionQueue
  -> ProgressWorker
  -> Transport plugin

两代实现目前通过公共门面共存。阅读时必须先确认配置实际启用哪一套,否则看到相同 API 名称却会追到不同执行路径。

十六、系列总结

Mooncake Transfer Engine 的本质不是一个 RDMA wrapper,而是一个异构地址空间传输运行时:

Segment 负责命名和发现
Memory Registration 负责建立访问能力
Transport 负责实际搬运
Batch/Operation 负责异步生命周期
Metadata/RPC 负责控制面
TENT Runtime 进一步负责选择、QoS 与容错

它之所以适合 KV Cache,不是因为理解 KV Cache 内容,而是因为能以较低控制开销搬运大量、可切片、可异步并行的内存区域,并在不同硬件环境下保持统一接口。

参考源码

  • tent/include/tent/transfer_engine.h
  • tent/src/transfer_engine.cpp
  • tent/src/runtime/transfer_engine_impl.cpp
  • tent/src/runtime/segment_manager.cpp
  • tent/src/runtime/segment_registry.cpp
  • tent/src/runtime/transport_selector.cpp
  • tent/src/runtime/progress_worker.cpp
  • tent/src/runtime/admission_queue.cpp
  • tent/src/runtime/qos_contract.cpp
  • tent/src/runtime/receiver_credit.cpp
  • tent/src/runtime/transport_loader.cpp