负载感知路由实践

更新时间:
复制 MD 格式

ALB扩展版支持负载感知路由,通过实时感知后端服务的负载指标(如请求队列长度、GPU Cache利用率、运行请求数等)智能调度流量,将请求优先分配给更空闲的后端,显著优化生成式AI等高负载、延迟敏感场景下的请求分布,降低推理延迟并提升整体吞吐与资源利用率。

适用场景

负载感知路由适用于后端各实例负载差异大、请求成本不均、对延迟敏感的场景,典型如下:

  • 生成式AI推理服务:LLM推理请求成本差异大,各实例的GPU显存、KV Cache利用率、排队情况实时波动。负载感知路由将请求调度到更空闲的实例,避免堆积到过载实例,降低首Token延迟(TTFT)与尾部延迟。

  • 后端负载不均:部分实例因个别高成本任务导致负载偏高时,静态调度算法会使路由到高负载实例的请求明显劣化。负载感知路由实时感知负载并动态规避高负载实例,改善不均衡带来的长尾延迟。

  • 高并发弹性推理集群:后端为ACK/ACS等容器集群中批量部署的推理副本时,可在集群整体高压下优化请求分布,减少极端排队请求,提升整体吞吐量。

方案架构

客户端请求到达扩展版ALB实例后,转发规则将流量交给关联了负载感知路由组件的服务器组。ALB转发节点周期性采集服务器组内各后端的实时指标,负载感知路由组件据此为后端评分排序,调度时优先选择负载最低(得分最优)的后端;当存在多个得分接近的最优后端时,再按加权轮询(WRR)算法进行二级调度。

image

  • 扩展版ALB实例:提供负载均衡和流量转发能力,转发节点同时负责后端指标采集。

  • 服务器组:支持服务器类型和IP类型,可包含ACK/ACS等容器后端。调度算法需选择加权轮询,并关联包含负载感知路由组件的服务扩展。

  • 服务扩展:承载负载感知路由组件,绑定到服务器组后生效。

  • 负载感知路由组件:内置到ALB转发链路的插件,基于转发节点采集的指标对后端评分排序,并输出最优后端供调度。

  • 后端推理服务:以Prometheus格式暴露推理指标(当前支持vLLM框架)供ALB采集。

调度原理

  1. 指标采集:转发节点周期性向后端采集路径(默认/metrics)发起HTTP请求采集指标,采集通道与健康检查通道相互独立。若某后端采集失败,则摘除该后端;若全部后端采集失败,则整体退化为加权轮询兜底。

  2. 评分排序:对各评分指标按后端集合归一化后,按配置的权重加权求和得到每个后端的负载得分。指标值越低代表越空闲,得分越优的后端越优先被选中。

  3. 二级调度:若排序结果存在多个得分接近(重叠)的最优后端,则在这些后端间按加权轮询选择权重高的后端;若无重叠,则直接选中最优后端。

负载感知路由默认支持以下决策指标:

指标

类型

说明

vLLM指标

TotalQueuedRequests
请求队列长度

Gauge

当前正在排队等待处理的请求数量。

vllm:num_requests_waiting

KVCacheUtilization
GPU Cache利用率

Gauge

当前用于缓存推理中间结果的KV Cache利用率百分比。

vllm:gpu_cache_usage_perc

RunningRequests
运行请求数

Gauge

当前正在处理中的请求数量。

vllm:num_requests_running

适用范围

  • 用户已获取ALB扩展版公测资格。

  • 用户已在华东2(上海)地域创建一个专有网络VPC1,分别在可用区B和可用区F创建交换机VSW1和VSW2。

  • 用户已在VPC1中创建包含GPU节点的ACK集群,并部署以Prometheus格式暴露推理指标的推理服务。本文以vLLM部署DeepSeek-R1-Distill-Qwen-1.5B为例,服务监听8000端口并在/metrics暴露指标。

操作步骤

1. (可选)部署示例推理服务

本步骤提供一个暴露Prometheus指标的vLLM推理服务示例(以DeepSeek-R1-Distill-Qwen-1.5B为例,使用的ECS规格为ecs.gn7i-c16g1.4xlarge),供后续负载感知路由采集指标并进行调度,验证测试章节也将基于该示例模型进行压测。如用户已按适用范围章节部署了推理服务,可跳过本步骤。也可参考部署Qwen大模型推理服务。

  1. 准备模型并配置存储卷。下载模型并上传至OSS后,参考配置OSS存储卷为集群配置存储卷PV和PVC(如example-oss-swap),供推理服务挂载模型。将模型转存至OSS并通过内网地址拉取,可避免直接从公网拉取耗时过长。

    # 1. 下载模型
    GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B.git
    cd DeepSeek-R1-Distill-Qwen-1.5B
    git lfs pull
    
    # 2. 上传模型至OSS
    ossutil mkdir oss://<Your-Bucket-Name>/DeepSeek-R1-Distill-Qwen-1.5B
    ossutil cp -r ./DeepSeek-R1-Distill-Qwen-1.5B oss://<Your-Bucket-Name>/DeepSeek-R1-Distill-Qwen-1.5B
  2. 在ACK集群中创建推理服务的Deployment与Service。以下配置通过vLLM启动推理服务,并在Pod上声明Prometheus采集注解,将8000端口的/metrics暴露为指标端点。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: deepseek-r1-distill-qwen-1.5b
      name: deepseek-r1-distill-qwen-1.5b
      namespace: default
    spec:
      replicas: 4
      selector:
        matchLabels:
          app: deepseek-r1-distill-qwen-1.5b
      template:
        metadata:
          labels:
            app: deepseek-r1-distill-qwen-1.5b
          annotations:
            prometheus.io/path: /metrics
            prometheus.io/port: "8000"
            prometheus.io/scrape: "true"
        spec:
          volumes:
            - name: model
              persistentVolumeClaim:
                claimName: example-oss-swap
            - name: dshm
              emptyDir:
                medium: Memory
                sizeLimit: 30Gi
          containers:
          - command:
            - sh
            - -c
            - vllm serve /models/DeepSeek-R1-Distill-Qwen-1.5B --port 8000 --trust-remote-code --served-model-name deepseek-r1-distill-qwen-1.5b --gpu-memory-utilization 0.95 --enforce-eager
            image: registry-cn-hangzhou.ack.aliyuncs.com/dev/vllm:0.10.0
            env:
            - name: SAFETENSORS_FAST_GPU_TRANSFER
              value: "0"
            - name: SAFETENSORS_MAX_HEADER_LENGTH
              value: "10000000"
            name: vllm
            ports:
            - containerPort: 8000
            readinessProbe:
              tcpSocket:
                port: 8000
              initialDelaySeconds: 30
              periodSeconds: 30
            resources:
              limits:
                nvidia.com/gpu: "1"
            volumeMounts:
              - mountPath: /models/
                name: model
              - mountPath: /dev/shm
                name: dshm
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: deepseek-r1-distill-qwen-1-5b-v1
    spec:
      type: ClusterIP
      ports:
      - port: 8000
        protocol: TCP
        targetPort: 8000
      selector:
        app: deepseek-r1-distill-qwen-1.5b
  3. 待Pod就绪后,进入任一Pod验证指标端点已正常暴露,返回内容应包含vllm:num_requests_waiting、vllm:gpu_cache_usage_perc、vllm:num_requests_running等指标。

    curl http://<Pod-IP>:8000/metrics

2. 创建扩展版 ALB 实例

  1. 登录ALB控制台,选择华东2(上海)地域,单击创建应用型负载均衡。

  2. 在购买页完成以下配置,单击立即创建。

    • 地域:选择华东2(上海)。

    • 实例网络类型:选择公网。

    • VPC和可用区:选择VPC1,勾选上海 可用区B和上海 可用区F后选择VSW1和VSW2。

    • 协议版本:选择IPv4。

    • 功能版本(实例费):选择扩展版。

  3. 在确认订单页面确认实例配置详情,单击立即开通。

3. 创建服务扩展并添加负载感知路由组件

  1. 在服务扩展控制台,单击创建服务扩展。在服务扩展配置区域,输入服务扩展名称如ext-load-aware-routing。

  2. 扩展类型默认选择插件,组件名称下拉选择负载感知路由,完成以下配置,然后单击创建。

    • 采集配置:

      • 域名:指标采集请求的Host请求头值。本文留空,即默认对服务器组内每个后端使用其自身的IP:Port分别采集。

      • 路径:指标采集的请求路径,本文使用/metrics。

      • 响应超时时间:默认5秒。

      • 间隔时间:设置为1秒。

    • 指标配置:同时勾选请求队列长度、GPU Cache 利用率、运行请求数,权重值分别配置为100、90、80。

负载感知路由组件必须搭配服务器类型或IP类型服务器组使用,且不支持与其他组件添加到同一个服务扩展。

4. 创建服务器组并关联服务扩展

创建一个服务器组承载后端推理副本,关联步骤3中创建的负载感知路由服务扩展。

  1. 在服务器组控制台,选择华东2(上海)地域。单击创建服务器组,完成以下配置并单击创建。

    • 服务器组类型:选择IP类型。

    • 服务器组名称:输入自定义名称如sgp-load-aware。

    • VPC:选择VPC1。

    • 选择调度算法:默认使用加权轮询。负载感知路由仅支持与加权轮询组合使用。

    • 关闭健康检查。

      本文后端Pod未提供ALB健康检查所需的接口,若开启,后端会被判定为不可用,导致负载感知路由被跳过而失效。若后端已提供健康检查接口,请保持开启,不推荐关闭。
      负载感知路由的指标采集内置探活能力,采集不到指标的后端会被自动摘除,从而实现类似健康检查的能力。
    • 勾选页面底部的适用于扩展版实例,开启关联服务扩展并使用已有服务扩展。选择步骤3中创建的ext-load-aware-routing。

  2. 待服务器组创建成功,单击添加后端服务器。在添加后端服务器窗口,添加已部署推理服务的POD地址(可在ACK集群列表-详情-网络-服务中获取)。单击添加IP地址以添加多个,完成后单击下一步。

  3. 在配置端口和权重步骤中,配置端口为8000,权重保持默认,单击确定。

5. 创建监听

  1. 在ALB控制台,单击目标实例ID进入实例详情页。在监听页签单击创建监听。

  2. 在配置监听步骤,选择监听协议选择HTTP,监听端口填写80,在高级配置中将连接请求超时时间设置为3600秒。完成后单击下一步。

    本文使用HTTP监听,以便聚焦验证负载感知路由对后端的调度效果、简化配置流程。在实际生产环境中,建议使用HTTPS监听并配置证书,以增强传输安全性。
    大模型推理请求(尤其输出Token较多时)单次响应耗时较长,若超过监听默认的请求超时时间(60秒),请求会被提前中断。本文将请求超时调大为3600秒以避免长响应被中断,请根据实际请求耗时调整该值。
  3. 在选择服务器组步骤,选择步骤4创建的服务器组sgp-load-aware,完成后单击下一步。

  4. 在配置审核步骤,确认配置并单击提交。

6. 设置域名解析

将自有域名通过CNAME解析指向ALB实例的DNS名称,客户端通过自有域名访问ALB。

本文以阿里云云解析DNS为例,对于非阿里云注册域名,需先将域名添加到云解析控制台。

  1. 在ALB控制台,复制目标实例的DNS 名称。

  2. 登录域名解析控制台,在目标域名的操作列单击解析设置。在解析设置页面单击添加记录。

  3. 参考以下信息添加CNAME记录,完成后单击确定。

    • 记录类型:选择CNAME。

    • 主机记录:输入域名前缀如test。假设用户自有根域名为example.com,则访问ALB的域名为test.example.com。

    • 解析请求来源和TTL时间:保持默认。

    • 记录值:输入ALB实例的DNS名称。

  4. 在弹出的解析变更确认对话框确认解析信息,单击确定。

7. 验证测试

使用压测工具vllm bench serve对后端发起压测。为规避公网链路的带宽、延迟与抖动对测试结果的干扰,本文从与 ALB 处于同一 VPC 的内网环境发起压测:单独部署一个基准测试Pod(仅安装vLLM工具并挂载相同模型、不启动推理服务)作为压测发起端,与被测后端分离,避免占用推理资源、干扰指标采集。

通过设置远超服务性能上限的并发目标,使后端GPU超负载运行,验证负载感知路由能否优化请求分布、减少极端排队请求、加快整体吞吐。

Kubernetes Service转发

向后端推理服务的Kubernetes Service发起压测,由Service在全部推理副本间按连接均摊,不感知实时负载。

将--host替换为该Service的ClusterIP(可在ACK集群列表-详情-网络-服务中获取)。

vllm bench serve \
  --backend vllm \
  --model /models/DeepSeek-R1-Distill-Qwen-1.5B \
  --served-model-name deepseek-r1-distill-qwen-1.5b \
  --trust-remote-code \
  --dataset-name random \
  --random-prefix-len 1000 \
  --random-input-len 3000 \
  --random-output-len 3000 \
  --random-range-ratio 0.2 \
  --num-prompts 3000 \
  --max-concurrency 600 \
  --host <Service-ClusterIP> \
  --port 8000 \
  --endpoint /v1/completions \
  --save-result \
  2>&1 | tee benchmark_svc.txt

ALB负载感知路由

向ALB实例发起压测,由负载感知路由在相同的推理副本间按实时负载调度。

将--host替换为ALB的VIP(可在实例详情页获取),其余参数保持一致。

vllm bench serve \
  --backend vllm \
  --model /models/DeepSeek-R1-Distill-Qwen-1.5B \
  --served-model-name deepseek-r1-distill-qwen-1.5b \
  --trust-remote-code \
  --dataset-name random \
  --random-prefix-len 1000 \
  --random-input-len 3000 \
  --random-output-len 3000 \
  --random-range-ratio 0.2 \
  --num-prompts 3000 \
  --max-concurrency 600 \
  --host <ALB-VIP> \
  --port 80 \
  --endpoint /v1/completions \
  --save-result \
  2>&1 | tee benchmark_alb.txt

两种方式的关键指标对比如下。以下为本文测试环境数据,仅供参考,实际效果请以用户自身环境的实测结果为准。

指标

Kubernetes Service转发

ALB负载感知路由

P99 TTFT(毫秒)

71872.40

60504.53

Mean TTFT(毫秒)

12709.49

12043.91

Median TTFT(毫秒)

7156.46

5492.57

Total Token throughput(tokens/s)

18285.60

18784.43

Benchmark duration(秒)

959.95

935.97

相同后端数量下,负载感知路由通过优先调度至低负载副本,首Token延迟(TTFT)明显降低——本文测试中P99 TTFT下降约16%、Median TTFT下降约23%,同时整体吞吐略有提升,请求延迟分布更平稳。

更多信息

计费说明

  • ALB扩展版:目前处于公测阶段,用户可免费体验。

  • ACK集群与GPU实例:后端推理服务运行在ACK集群的GPU节点上,按对应的容器服务与ECS实例规则计费。若出于测试目的创建,建议使用按量付费实例并及时释放。

  • 域名和公网DNS解析费用:除了需要支付域名供应商的域名费用外,在阿里云配置公网DNS解析需要支付公网权威解析费用。

使用限制

  • 指标采集请求基于HTTP 1.1协议、通过IPv4地址发起,暂不支持IPv6后端。

  • 单个后端的指标采集响应包体默认限制为10 KB,超出部分会被丢弃,可能导致指标采集不全。负载感知路由仅使用vllm:num_requests_waiting、vllm:gpu_cache_usage_perc、vllm:num_requests_running三项指标,建议将这些指标放在指标输出的前10 KB内,以确保被正常采集。

常见问题

开启负载感知路由后,请求分布与加权轮询无差异?

请确认下列设置:

  • 调度算法:服务器组的调度算法已选择加权轮询。

  • 服务扩展关联:服务器组已正确关联包含负载感知路由组件的服务扩展。

  • 指标暴露:后端在指标采集路径正常暴露vLLM指标。若指标采集失败,负载感知路由会退化为加权轮询兜底。

  • 健康检查:确认健康检查状态是否正常。开启后,健康检查失败的节点会被摘除并跳过负载感知调度;当所有节点均异常时,负载感知路由整体退化为加权轮询兜底。