版本:v26.06

AI推理KVCache索引管理

特性介绍

cache-indexer是面向大语言模型推理场景的全局KVCache索引组件,统一维护L1(推理实例本地HBM)与L3(推理实例内存缓存)两层KVCache视图。路由组件可调用cache-indexer查询候选推理实例的KVCache命中率,从而进行更准确的请求级调度。

应用场景

cache-indexer适用于在Kubernetes集群中部署大语言模型推理服务,并需要基于KVCache命中情况优化请求路由的场景。

  • 多实例推理后端:多个vLLM实例同时提供服务,需要根据请求前缀缓存命中情况选择更合适的实例。
  • KVCache感知路由:Hermes-router等路由组件需要获取L1/L3命中率,用于KVCache aware类路由策略。
  • 分布式缓存复用:推理服务使用Mooncake等分布式缓存管理系统,希望将已下沉到内存的KVCache纳入调度依据。
  • 动态扩缩容场景:推理实例或Mooncake Master发生上下线时,需要cache-indexer自动发现并更新索引采集目标。

能力范围

cache-indexer当前提供以下能力:

  • 支持通过Kubernetes Pod label动态发现vLLM Pod与Mooncake Master Pod。
  • 支持订阅vLLM ZMQ KV-event,维护L1 KVCache索引。
  • 支持轮询Mooncake Master,维护L3 KVCache索引。
  • 支持通过/kv-cache/hit-rate接口查询候选实例的L1/L3 KVCache命中率。
  • 支持通过Helm Chart独立部署,也支持作为InferNex子组件集成部署。

说明

  • cache-indexer不包含tokenizer能力,调用方需要在请求中传入已经完成编码的token_ids
  • 因Mooncake V1暂未提供SSD层KVCache查询接口,L3索引不包含SSD中的KVCache信息。

软件依赖

cache-indexer的L1/L3命中率依赖推理引擎、分布式缓存管理系统与自身配置保持一致。当前已验证组合如下。

表1 cache-indexer依赖组件

组件类别当前已验证版本说明
推理引擎(L1)vLLM 0.13.0vLLM 0.18.0提供L1 KVCache;需开启prefix caching与KV events,并与cache-indexer使用一致的block计算参数。
分布式缓存管理系统(L3)Mooncake 0.3.7提供L3 KVCache;需支持/get_all_keys/query_key/get_all_segments
Kubernetes1.28+cache-indexer通过Kubernetes API进行服务发现,需要具备podsget/list/watch权限。

亮点特征

  • L1/L3双层视图:同时维护推理实例本地HBM缓存和分布式内存缓存视图。
  • 统一KVCache block计算机制:复刻vLLM block hash计算逻辑,使查询侧计算结果与vLLM事件、Mooncake key对齐。
  • 动态服务发现:周期发现vLLM Pod与Mooncake Master Pod,自动驱动订阅和轮询目标更新。
  • 轻量接口:只接收token_idsblock_sizecache_salt等必要输入,不在cache-indexer内执行tokenizer。

实现原理

cache-indexer位于路由决策路径上,主链路如下。

  1. cache-indexer通过Kubernetes API Server列举带特定label的vLLM Pod与Mooncake Master Pod,构造发现快照。
  2. 对每个vLLM Pod启动一路ZMQ SUB,订阅BlockStored / BlockRemoved / AllBlocksCleared事件,写入L1索引。
  3. 对Mooncake Master周期调用GET /get_all_keysGET /query_key,拉取block副本列表,并通过GET /get_all_segments解析vLLM Pod IP地址到Mooncake client传输端点的映射,写入L3索引。
  4. 路由组件调用POST /kv-cache/hit-rate,cache-indexer在L1/L3两张索引上分别计算最长连续前缀命中并返回。

总体架构如下。

图1 cache-indexer总体架构 架构图

安装

独立部署

本节介绍在已有推理引擎和分布式缓存管理系统的集群中,单独部署cache-indexer。

组件规格

cache-indexer独立部署时,需要配套组件提供可采集的L1/L3数据。

组件规格说明
推理引擎当前支持vLLM,已验证vLLM 0.13.0vLLM 0.18.0;需要开启prefix caching与KV events。
分布式缓存管理系统当前支持Mooncake,已验证Mooncake 0.3.7;需要提供Mooncake Master admin HTTP接口。
cache-indexer通过Helm chart部署,默认提供ClusterIP Servicecache-indexer-service:8080

说明

不部署推理引擎和分布式缓存管理系统时,cache-indexer Pod仍可启动,健康检查和查询接口可访问,但L1/L3命中率均为0

前提条件

在开始安装前,请确保满足以下条件。

  • 环境要求

    • Kubernetes集群:1.28+
    • Helm工具:用于部署cache-indexer chart。
    • 用户具备在目标命名空间创建Deployment、Service、ConfigMap、ServiceAccount、Role、RoleBinding的权限。
  • 组件要求

    • 如需L1命中率,集群中需要部署vLLM推理实例,并按推理引擎(以vLLM为例)章节配置标签、环境变量、启动参数和ZMQ端口。
    • 如需L3命中率,集群中需要部署Mooncake Master与Mooncake client,并按分布式缓存管理系统(以Mooncake为例)章节配置标签、端口和client参数。
    • 如仅验证cache-indexer安装与接口连通性,可先不部署推理引擎和分布式缓存管理系统。
  • 硬件要求

    • cache-indexer本身无特殊硬件要求,可运行在标准CPU节点上。

快速安装

  1. 拉取cache-indexer Helm Chart包。

    bash
    helm pull oci://cr.openfuyao.cn/charts/cache-indexer --version 26.6.0
  2. 解压Chart包。

    bash
    tar -xzvf cache-indexer-26.6.0.tgz
  3. 安装cache-indexer。

    bash
    helm -n <NAMESPACE> install <RELEASE_NAME> ./cache-indexer

    参数说明如下。

    • <NAMESPACE>:cache-indexer的安装命名空间,也是默认服务发现范围。
    • <RELEASE_NAME>:Helm release名称,主要影响Deployment、ConfigMap、ServiceAccount等资源名。
    • --create-namespace(可选):新创建命名空间时使用。
  4. 验证部署。

    bash
    kubectl -n <NAMESPACE> get pod -l app.kubernetes.io/name=cache-indexer
    kubectl -n <NAMESPACE> get svc cache-indexer-service

InferNex集成部署

本节介绍通过InferNex集成部署cache-indexer。

组件规格

InferNex是openFuyao社区提供的AI推理服务软件套件,现已集成cache-indexer。通过InferNex部署时,至少需要开启以下组件。

表2 通过InferNex部署时组件最小集

组件最小要求
inference-backend必须开启,用于部署vLLM推理后端;如需L3命中率,需要启用Mooncake Store。
cache-indexer必须开启,用于采集L1/L3 KVCache并提供/kv-cache/hit-rate
hermes-router建议开启,用于消费cache-indexer的命中率结果并执行KVCache aware路由。

InferNex最新Chart中,vLLM、Mooncake、cache-indexer的关键联动配置已在values中暴露;部署时需要确保PYTHONHASHSEED、Hash算法、ZMQ端口名和Mooncake Master HTTP端口名保持一致。

前提条件

  • Kubernetes集群可访问oci://cr.openfuyao.cn或用户已准备离线Chart包。
  • 已具备InferNex所需的推理硬件、镜像拉取权限和Helm安装权限。

快速安装

  1. 拉取InferNex Chart包。版本使用release-26.6.0

    bash
    helm pull oci://cr.openfuyao.cn/charts/infernex --version 26.6.0
  2. 解压Chart包。

    bash
    tar -xzvf infernex-26.6.0.tgz
  3. 根据环境修改values.yaml。至少确认以下开关和参数。

    yaml
    inference-backend:
      services:
        - enabled: true
          kvTransferConfig:
            mooncake:
              use_store: true
    
    hermes-router:
      enabled: true
    
    cache-indexer:
      enabled: true
  4. 安装InferNex。以下命令以release名称infernex为例。

    bash
    helm install -n <namespace> infernex ./infernex

具体部署方式与网关、后端、模型配置请参考InferNex用户手册

使用KVCache命中率查询服务

cache-indexer对外提供集群内部接口POST /kv-cache/hit-rate。该接口当前主要由Hermes-router等集群内部路由组件调用,不面向集群外部用户直接暴露。

调用流程如下。

  1. 路由组件构造候选推理实例IP地址列表,调用cache-indexer的/kv-cache/hit-rate

    请求示例如下。

    bash
    curl -X POST http://cache-indexer-service:8080/kv-cache/hit-rate \
      -H 'Content-Type: application/json' \
      -d '{
        "server_ip": ["this.is.pod.ip"],
        "body": {
          "token_ids": [9707, 0, 358, 3900, 374, 1234, 5678, 9012],
          "cache_salt": "",
          "block_size": 128
        }
      }'

    请求参数说明如下。

    表3 请求参数说明

    参数说明
    server_ip候选推理实例Pod 地址列表,cache-indexer按输入顺序返回评分结果。
    body.token_ids已由上游tokenizer完成编码的token ID序列。
    body.cache_salt与对应vLLM推理请求实际使用的cache_salt一致;未使用时传空字符串。
    body.block_size与vLLM--block-size一致的KV block大小,建议为128的倍数。
  2. cache-indexer根据token_idsblock_sizecache_salt计算请求block hash序列。

  3. cache-indexer分别查询L1/L3索引,返回每个候选实例的命中率。 响应示例如下。

    json
    {
      "server_score_list": [
        {
          "server_ip": "this.is.pod.ip",
          "l1_hit_ratio": 1.0,
          "l3_hit_ratio": 1.0
        }
      ],
      "message": "",
      "status": 0
    }

    响应参数说明如下。

    表4 响应参数说明

    参数说明
    server_score_list[].server_ip候选推理实例Pod IP地址。
    server_score_list[].l1_hit_ratioL1最长连续前缀命中率,范围[0,1]
    server_score_list[].l3_hit_ratioL3最长连续前缀命中率,范围[0,1]
    message业务提示信息,正常返回为空字符串。
    status业务状态码。成功返回0;错误场景下按当前实现返回对应HTTP状态码,包括400(空请求体、非法JSON、未知字段、server_ip为空或block_size小于等于 0)、405(请求方法不是 POST)、413(请求体超过大小限制)和500(命中率计算失败)。

参数配置说明

cache-indexer

对应配置文件见cache-indexervalues.yaml

yaml
image:
  repository: "cr.openfuyao.cn/openfuyao/cache-indexer"
  tag: "26.6.0"
  pullPolicy: IfNotPresent

service:
  name: cache-indexer-service
  port: 8080
  targetPort: 28080

resources:
  limits:
    cpu: "1"
    memory: 2Gi
  requests:
    cpu: 100m
    memory: 128Mi

log:
  level: info

http:
  shutdownTimeout: 10s
  readHeaderTimeout: 10s
  readTimeout: 30s
  writeTimeout: 30s
  idleTimeout: 120s
  maxHeaderBytes: 1048576
  maxHitRateBodyBytes: 4194304

blockKey:
  pythonHashSeed: "0"
  prefixCachingHashAlgo: sha256_cbor
  useIntBlockHashes: true

discovery:
  refreshInterval: 10s
  segmentsFetchTimeout: 2s
  labels:
    engineKey: openfuyao.com/engine
    engineValue: vllm
    pdRoleKey: openfuyao.com/pdRole
    pdRoleValue: [prefill, aggregate]
    kvManagerKey: openfuyao.com/kvmanager
    kvManagerValue: mooncake
  vllm:
    zmqPortName: zmq-pub
  mooncakeMaster:
    httpPortName: http
    rpcPortName: rpc
    httpPort: 9003
    rpcPort: 0

ingest:
  l1:
    backoffInitial: 1s
    backoffMax: 30s
  l3:
    scheme: http
    pollInterval: 10s
    httpTimeout: 5s

serviceAccount:
  create: true
  name: ""

podAnnotations: {}
podLabels: {}
nodeSelector: {}
tolerations: []
affinity: {}

表5 Helm Chart关键参数说明

参数说明
image.repositorycache-indexer镜像仓库。
image.tagcache-indexer镜像标签。
image.pullPolicy镜像拉取策略。
service.namecache-indexer Service名称,路由组件通过该名称访问。
service.portService对外端口。
service.targetPortcache-indexer容器HTTP侦听端口。
resources.requestsPod资源请求值。
resources.limitsPod资源限制值。
log.level日志级别,可选debuginfoerror
http.shutdownTimeoutHTTP服务优雅停止超时。
http.readHeaderTimeoutHTTP请求头读取超时。
http.readTimeoutHTTP请求读取超时。
http.writeTimeoutHTTP响应写入超时。
http.idleTimeoutHTTP keep-alive空闲超时。
http.maxHeaderBytesHTTP请求头大小上限。
http.maxHitRateBodyBytes/kv-cache/hit-rate请求体大小上限。
blockKey.pythonHashSeed必须与vLLMPYTHONHASHSEED一致。
blockKey.prefixCachingHashAlgo必须与vLLM--prefix-caching-hash-algo一致。
blockKey.useIntBlockHashes必须与vLLMVLLM_KV_EVENTS_USE_INT_BLOCK_HASHES一致。
discovery.refreshIntervalKubernetes Pod发现轮询周期。
discovery.segmentsFetchTimeout调用Mooncake Master/get_all_segments的超时。
discovery.labels.engineKey / engineValuevLLM Pod发现标签。
discovery.labels.pdRoleKey / pdRoleValue参与命中率计算的推理角色标签。
discovery.labels.kvManagerKey / kvManagerValueMooncake Master发现标签。
discovery.vllm.zmqPortNamevLLM KV-event ZMQ端口名。
discovery.mooncakeMaster.httpPortNameMooncake Master admin HTTP端口名;要与Mooncake Master Pod中对应端口的ports[].name名称一致。
discovery.mooncakeMaster.rpcPortNameMooncake Master RPC端口名。
discovery.mooncakeMaster.httpPortadmin HTTP端口名未命中时使用的兜底端口;数值要与Mooncake--metrics_port一致。
discovery.mooncakeMaster.rpcPortRPC端口名未命中时使用的兜底端口;0表示不启用。
ingest.l1.backoffInitialL1 ZMQ订阅重连初始backoff。
ingest.l1.backoffMaxL1 ZMQ订阅重连最大backoff。
ingest.l3.scheme访问Mooncake Master使用的协议。
ingest.l3.pollIntervalL3索引刷新周期。
ingest.l3.httpTimeout单次Mooncake HTTP请求超时。
serviceAccount.create是否为cache-indexer创建ServiceAccount。
serviceAccount.name指定ServiceAccount名称;为空时由chart自动生成。
podAnnotations附加到cache-indexer Pod的注解。
podLabels附加到cache-indexer Pod的标签。
nodeSelectorPod节点选择器。
tolerationsPod容忍配置。
affinityPod亲和性配置。

推理引擎(以vLLM为例)

以下片段示意vLLM Pod / Deployment中与cache-indexer联动的关键字段,不是一份完整部署清单。

yaml
metadata:
  labels:
    openfuyao.com/engine: vllm
    openfuyao.com/pdRole: aggregate

spec:
  containers:
    - name: vllm
      env:
        - name: PYTHONHASHSEED
          value: "0"
        - name: VLLM_KV_EVENTS_USE_INT_BLOCK_HASHES
          value: "1"
      args:
        - --enable-prefix-caching
        - --block-size=128
        - --prefix-caching-hash-algo=sha256_cbor
        - --kv-events-config={"enable_kv_cache_events":true,"publisher":"zmq","topic":"kv-events"}
      ports:
        - name: zmq-pub
          containerPort: 5557

表6 推理引擎(vLLM)关键参数说明

参数说明
openfuyao.com/enginevLLM Pod发现标签,需与discovery.labels.engineValue匹配。
openfuyao.com/pdRole推理角色标签,默认prefillaggregate会进入候选集。
PYTHONHASHSEED必须与cache-indexerblockKey.pythonHashSeed一致。
VLLM_KV_EVENTS_USE_INT_BLOCK_HASHES必须与cache-indexerblockKey.useIntBlockHashes一致。
--enable-prefix-caching开启prefix caching,否则无法形成有效前缀命中。
--block-sizeKV block大小,需与查询请求body.block_size一致。
--prefix-caching-hash-algoblock hash算法,需与cache-indexerblockKey.prefixCachingHashAlgo一致。
--kv-events-config开启vLLM KV-event发布,供cache-indexer订阅L1事件。
ports[].name=zmq-pubKV-event ZMQ端口名,需与cache-indexerdiscovery.vllm.zmqPortName一致。

分布式缓存管理系统(以Mooncake为例)

以下片段分别示意Mooncake Master Pod / Deployment、Service和Mooncake client中与cache-indexer联动的关键字段,不是一份完整部署清单。

Mooncake Master Pod/Deployment

yaml
metadata:
  labels:
    openfuyao.com/kvmanager: mooncake

spec:
  containers:
    - name: mooncake-master
      args:
        - --port=50051
        - --metrics_port=9003
      ports:
        - name: rpc
          containerPort: 50051
        - name: http
          containerPort: 9003

表7 Mooncake Master关键参数说明

参数说明
openfuyao.com/kvmanagerMooncake Master发现标签,需与cache-indexerdiscovery.labels.kvManagerValue匹配。
--portMooncake Master RPC侦听端口。
--metrics_portMooncake Master admin HTTP侦听端口,cache-indexer通过该端口轮询L3信息;数值需与discovery.mooncakeMaster.httpPort一致。
ports[].name=rpcRPC容器端口名,可供ServicetargetPort引用。
ports[].name=httpadmin HTTP容器端口名,需与cache-indexerdiscovery.mooncakeMaster.httpPortName对齐;如果实际部署使用其他端口名,需要同步修改该配置。

Mooncake Master Service

Mooncake Master需要对外提供admin HTTP Service端口,以支持cache-indexer轮询获取L3 KVCache信息。

yaml
service:
  ports:
    - name: rpc
      port: 30089
      targetPort: rpc
    - name: http
      port: 9003
      targetPort: http

表8 Mooncake Service关键参数说明

参数说明
service.ports[].name=rpcMooncake Master RPC Service端口名。
service.ports[].port=30089提供给vLLM / Mooncake client访问的Master RPC Service端口。
service.ports[].name=httpMooncake Master admin HTTP Service端口名。
service.ports[].port=9003提供给cache-indexer访问的admin HTTP Service端口。

Mooncake client配置

Mooncake client实际负责管理本地内存中的KVCache,需要配置以确保能被cache-indexer正确识别。

yaml
mooncake:
  use_store: true
  config: |
    local_hostname: "$POD_IP"
    metadata_server: "redis://redis-service:6379"
    master_server_address: "mooncake-master-service:30089"
    device_name: ""
    protocol: "ascend"
    global_segment_size: 42949672960
    use_ascend_direct: true

表9 Mooncake Client关键参数说明

参数说明
mooncake.use_store开启Mooncake Store,L3 KVCache才会写入Mooncake。
local_hostnameMooncake client本地传输端点来源;建议使用Pod IP地址,便于cache-indexer通过/get_all_segments反查transport_endpoint
metadata_serverMooncake元数据服务地址,需与集群中Redis等元数据组件地址一致。
master_server_addressMooncake Master RPC Service地址,需与Mooncake Service RPC端口一致。
device_name设备名称,按Mooncake后端要求配置;为空时使用默认设备选择逻辑。
protocolMooncake数据传输协议,需与推理硬件和Mooncake部署方式一致。
global_segment_sizeMooncake全局segment大小,按模型规模、并发量和缓存容量规划。
use_ascend_direct昇腾场景下是否启用直连传输能力,需与运行环境能力匹配。