☰
Mooncake Store 的 OSS 对象存储卸载(Offload)部署指南:架构、配置与故障排查
2026/10/5 13:04:35 网站建设 项目流程
  • 人工智能
  • 大模型
  • 模型推理服务
  • 后端

【免费下载链接】Mooncake

Mooncake is the serving platform for Kimi, a leading LLM service provided by Moonshot AI.

项目地址:https://gitcode.com/gh_mirrors/mo/Mooncake
点击查看免费下载

导读

本文介绍 Mooncake 项目中如何通过FileStorage既有卸载路径,将对象数据以 key-based 形式卸载(Offload)到 OSS/S3 等对象存储服务。你将掌握 OSS 卸载的部署拓扑、完整环境变量配置表、master 与 real client 的启动方式,以及初始化失败、鉴权报错、副本不可读等常见故障的排查思路。文中同时结合 oss_adapter_config.cpp 等源码实现,说明每个配置项的解析逻辑与取值边界,帮助你在真实集群中正确落地。

概览:OSS 卸载是什么

对象存储服务(如阿里云 OSS、AWS S3)提供基于 key 的存储语义。Mooncake Store 通过ObjectStorageAdapter在现有FileStorage卸载路径中接入对象存储:与本地 SSD、NVMe KV 后端一致,master 记录 real client 所拥有的LOCAL_DISK副本,读取方仍然通过该 owner 访问数据负载。对象存储在这里不是一种独立的一等副本类型,而是LOCAL_DISK副本背后的一种存储载体。

需要特别强调的是:本文示例使用的是 OSS 适配器。其他对象存储服务需要与之兼容的适配器实现,仅更换 endpoint 并不能获得 S3 支持——OSS 适配器的签名协议是 OSS 特有的,S3 必须使用专门的适配器。

更底层的设计细节(读写路径、物理 key 映射、批量执行与失败语义)可参考 OSS Backend Design。

前置条件

在部署 OSS 卸载之前,需要准备:

  • 一个已存在的 OSS bucket,且其 endpoint 可以从每个卸载 owner 所在节点访问。不需要挂载 OSS 文件系统。
  • 在所选命名空间内具备 PUT、GET、HEAD、LIST、DELETE 权限的凭证;支持 STS 临时凭证。
  • 每个卸载 owner 使用独立的对象 key 前缀。
  • 一个已存在的、绝对路径、可写、非符号链接的目录,用于MOONCAKE_OFFLOAD_FILE_STORAGE_PATH——这是通用FileStorage初始化所必需的。需要说明:该目录不会为 OSS 启用本地 SSD 缓存。
  • libcurl 与 OpenSSL 的开发库及头文件。

构建支持

当环境中存在 libcurl 与 OpenSSL 时,构建会自动启用 OSS 适配器,无需 OSS SDK,也不需要额外的 OSS 专用构建开关。构建与安装 Mooncake 的完整步骤请参考 构建指南。

批量 I/O 使用curl_multi_wait,因此不要求libcurl 7.66.0 以上版本。上传缓冲区调优是可选能力:当 libcurl 头文件版本早于 7.62.0 时,将使用库默认值(见下文配置章节)。

部署拓扑

拓扑中只有一个关键结论值得记住:只有卸载 owner 需要 OSS 凭证。master 与请求方客户端都不会直接读写 OSS 对象——读取方通过 owner 上的batch_get_offload_objectRPC 与 Transfer Engine 获取数据。

从源码看,请求链路是:请求方客户端查询 master 获得LOCAL_DISKowner 与对象大小 → 向 owner 发起batch_get_offload_object→ owner 的FileStorage调用BatchLoad填充 staging buffer → OSS 适配器并发执行GetBatch→ 字节经 Transfer Engine 传回请求方。该 RPC 协程把阻塞工作投递到既有 blocking pool,worker 等待 HTTP 批量完成后返回,不引入专用 OSS worker 池(见 oss-backend.md 的 Read Path 章节)。

配置

在每个卸载 owner 的环境中设置后端与 OSS 相关变量:

export MOONCAKE_OFFLOAD_STORAGE_BACKEND_DESCRIPTOR=distributed_storage_backend export MOONCAKE_OFFLOAD_FILE_STORAGE_PATH=/data/file_storage export MOONCAKE_DISTRIBUTED_FS_TYPE=oss export MOONCAKE_DISTRIBUTED_ROOT_DIR=/mooncake/my-cluster/owner-1 export MOONCAKE_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com export MOONCAKE_OSS_BUCKET=my-mooncake-bucket export MOONCAKE_OSS_REGION=cn-hangzhou # MOONCAKE_OSS_ACCESS_KEY_ID 与 MOONCAKE_OSS_ACCESS_KEY_SECRET # 请通过你的凭证管理机制提供,不要写死在脚本中。

请将示例中的 endpoint、bucket、region 与 owner 前缀替换为你自己的部署值。注意:每个FileStorage实例只选择一个后端,OSS 不会与本地文件或 NVMe KV 后端在同一实例内并存。

后端与命名空间

环境变量OSS 取值说明
MOONCAKE_OFFLOAD_STORAGE_BACKEND_DESCRIPTORdistributed_storage_backend选择承载 OSS 适配器的后端。
MOONCAKE_OFFLOAD_FILE_STORAGE_PATH默认/data/file_storage通用初始化所需的本地目录;对象负载实际写入 OSS。
MOONCAKE_DISTRIBUTED_FS_TYPEoss选择对象存储模式,而非文件系统适配器。
MOONCAKE_DISTRIBUTED_ROOT_DIRowner 专属前缀使用绝对风格路径;适配器会去除首尾斜杠。这不是挂载点。

OSS 卸载不需要Master 侧的 DFS 配置,也不需要禁用单独配置的 DFS tier。但在卸载 owner 环境中,MOONCAKE_DFS_FS_ADAPTER与MOONCAKE_DFS_ROOT_DIR会覆盖对应的MOONCAKE_DISTRIBUTED_*值(两者共享同一配置解析器),因此使用上述示例时请保持这些 override 不设置。

Endpoint 与凭证

环境变量默认值说明
MOONCAKE_OSS_ENDPOINT必填包含http://或https://的 endpoint。别名:OSS_ENDPOINT。
MOONCAKE_OSS_BUCKET必填已存在的 bucket。别名:OSS_BUCKET。
MOONCAKE_OSS_REGION必填OSS 签名区域。别名:OSS_REGION。
MOONCAKE_OSS_ACCESS_KEY_ID非匿名时必填AccessKey ID。别名:OSS_ACCESS_KEY_ID。
MOONCAKE_OSS_ACCESS_KEY_SECRET非匿名时必填AccessKey Secret。别名:OSS_ACCESS_KEY_SECRET。
MOONCAKE_OSS_SECURITY_TOKEN空可选的 STS token。别名:OSS_SESSION_TOKEN。
MOONCAKE_OSS_PATH_STYLEfalse使用endpoint/bucket/key路径寻址,而非虚拟主机风格 bucket 寻址。
MOONCAKE_OSS_ANONYMOUSfalse禁用签名;仅用于测试 endpoint 或配置了公共访问的场景。

关于配置解析,源码 oss_adapter_config.cpp 给出了几个值得注意的实现事实:

  • 主名优先于别名:ReadPrimaryOrAlias的逻辑是主变量存在(即使显式为空字符串)就使用主变量值,否则回退到别名。对应的 oss_adapter_config_test.cpp 中EmptyPrimaryOverridesCompatibilityAlias用例验证了"显式空主名会覆盖别名"这一行为。
  • 配置在初始化时读取:修改环境变量不会重新配置已运行的适配器,也不会刷新其凭证;测试InitReadsCurrentEnvironmentEachTime表明每次Init()都重新读取当前环境,但运行期不会热更新。
  • 字符串归一化:endpoint 会去除尾部/(while (!config.endpoint.empty() && config.endpoint.back() == '/')),security token 会trim空白字符。
  • 必填校验顺序:endpoint/bucket/region 三者缺失最先报错;非匿名模式下 access key 缺失返回INVALID_PARAMS。无效布尔值(如MOONCAKE_OSS_PATH_STYLE=invalid)会在告警后按默认值false处理,见测试InvalidBoolValuesWarnAndUseFalse。

后端并发与健康检查

环境变量默认值说明
MOONCAKE_OSS_MAX_CONNECTIONS64每个批次内最大准入请求数与每 host 连接总数上限;最小值为1。不是进程级限制。
MOONCAKE_OSS_RECEIVE_BUFFER_SIZE1048576(1 MiB)批量请求的 libcurl 接收缓冲区建议值,钳制在 16 KiB–10 MiB;单请求 GET 保持库默认。
MOONCAKE_OSS_UPLOAD_BUFFER_SIZE1048576(1 MiB)PutV/PutBatch的上传缓冲区建议值,钳制在 16 KiB–2 MiB;仅在 libcurl 头文件 ≥ 7.62.0 时生效,否则用库默认。
MOONCAKE_DISTRIBUTED_HEALTH_CHECKfalse初始化时写入并回读一个探针对象,随后尽力删除。

数值调优参数使用十进制整数。无效或越界整数回退到默认值,然后再应用上述钳制边界——这一点在测试TuningValuesKeepExistingBounds中得到验证:max_connections下限为 1、receive_buffer_size上限 10 MiB、upload_buffer_size上限 2 MiB,且越界/非法输入会打印 "using default ..." 告警后回落。缓冲区大小只是 libcurl 的建议值,不是 TCP socket 缓冲区大小,也不保证吞吐。

通用卸载心跳默认 10 秒,通过MOONCAKE_OFFLOAD_HEARTBEAT_INTERVAL_SECONDS配置。其他通用客户端设置见 SSD Offload。

启动 Mooncake

以启用卸载的方式启动 master:

mooncake_master --rpc_port=50051 --enable_offload=true

应用上述后端配置后,创建必需的本地目录并启动一个 real client。以下示例使用本地 master 与 TCP 传输:

mkdir -p /data/file_storage export MOONCAKE_MASTER=127.0.0.1:50051 export MOONCAKE_LOCAL_HOSTNAME=127.0.0.1 export MOONCAKE_PROTOCOL=tcp export MOONCAKE_TE_META_DATA_SERVER=P2PHANDSHAKE export MOONCAKE_OFFLOAD_ENABLED=true python -m mooncake.mooncake_store_service

多节点部署请使用可路由地址。该 launcher 示例假设MOONCAKE_CONFIG_PATH未设置;否则服务配置文件优先。

嵌入式 real-client 模式使用相同的后端与 OSS 变量:在调用MooncakeDistributedStore.setup()时传入enable_ssd_offload=True与ssd_offload_path,同时保留常规的连接与内存参数。嵌入式与独立 real-client 两种部署模式的区别详见 SSD Offload guide。

源码视角:批量执行与失败语义

从 oss_adapter.h 与设计文档可以提炼出 OSS 适配器的运行时行为,这对排障很有帮助:

  • 物理 key 映射:physical_key = owner_prefix + "/" + URIEncode(storage_key),对象体为拼接的 payload 分片;前缀为空时省略分隔符。LIST 会把匹配的对象 key 解码回逻辑存储 key,供ScanMeta注册元数据。没有分片/偏移分配、没有对象级 UUID 描述符、没有根 manifest、也没有适配器级校验和信封。
  • 批量执行:每次GetBatch/PutBatch创建一个临时CURLM和每个请求一个 easy handle;同时准入最多MOONCAKE_OSS_MAX_CONNECTIONS个请求,随完成逐批准入。等待准入的请求留在CURLM之外,避免在 libcurl 连接队列中消耗传输超时。连接在批次内复用、跨批次不复用;不同调用线程可并发执行独立批次,限制按批次生效。完成顺序可能与输入顺序不同,但返回的结果向量保持输入顺序与数量。
  • 并发与所有权:适配器 API 是同步的(返回前完成批量处理与清理);每个批次独占自己的请求上下文与 libcurl 句柄,无共享CURLM或全局锁。下载缓冲区、上传 iovec 数组与上传负载必须存活到调用返回,使用中不得修改。失败的读可能已部分改写目标缓冲区,不得将其当作有效数据消费。
  • 失败语义(摘自 oss-backend.md 的 Failure Semantics 表):GET 遇到缺失对象返回FILE_NOT_FOUND;范围 GET 需要 HTTP 206 与请求长度;PUT 非成功状态码视为写失败,不会把该对象报告为成功卸载;超时的 PUT 无法证明 OSS 是否已存储数据;一个对象失败时保留逐对象结果,成功的上传不会自动删除——批量不是事务。

故障排查

适配器无法初始化

依次检查:构建依赖(libcurl、OpenSSL 开发库与头文件)、必填的 endpoint/region/凭证设置、本地目录是否存在且可写、是否存在残留的MOONCAKE_DFS_*override(它们会覆盖MOONCAKE_DISTRIBUTED_*配置)。可选的健康检查会实际访问 OSS,但它只验证 OSS 访问通路,不覆盖完整的 Store 读路径。

请求报鉴权或权限错误

核对 endpoint、签名 region、bucket 权限以及 STS token 的有效期。适配器不会自动刷新凭证——token 过期后需要重启或重新初始化加载新凭证。

对象已在 OSS 中,但无法通过 Store 读取

bucket 里有一个对象不等于可读的 Store 副本。master 必须拥有该 key 的元数据且存在可达的 owner。务必保持前缀 owner 专属:共享同一个 bucket 并不会让不同 owner 变得可互换(owner 前缀防止互相覆盖对象)。

SSD 容量指标与 OSS 实际用量不一致

MOONCAKE_OFFLOAD_TOTAL_SIZE_LIMIT_BYTES提供的是一个配置的容量值(默认 2 TiB),而非查询 OSS bucket 得到的容量。master 的用量统计追踪的是已注册的LOCAL_DISK副本。这里 OSS 没有后端配额强制,也没有自动对象 GC——删除 master 元数据不会触发 OSS DELETE,因此这些指标既不是物理 bucket 用量,也不是云成本限额。当前实现同样不支持multipart 上传、自动并行范围切分与自动凭证刷新(见 oss-backend.md 的 Current Limitations)。

  • 人工智能
  • 大模型
  • 模型推理服务
  • 后端

【免费下载链接】Mooncake

Mooncake is the serving platform for Kimi, a leading LLM service provided by Moonshot AI.

项目地址:https://gitcode.com/gh_mirrors/mo/Mooncake
点击查看免费下载

相关推荐

上一篇:3步搞定京东抢购自动化,告别手速焦虑的终极方案
下一篇:Orleans Journaling 的 Redis 存储提供程序:从配置到原理的完整实战指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询