自适应算法指南

自适应算法根据系统资源使用率动态调整限流阈值,解决固定阈值无法应对负载变化的问题。

为什么需要自适应

传统限流使用固定阈值,存在两个问题:

  • 阈值过高:负载高时无法有效保护系统
  • 阈值过低:负载低时浪费系统资源

自适应算法通过实时采集资源指标,动态调整限流阈值,使系统始终运行在最佳状态。

工作原理

资源采集器 → 采集资源指标(CPU/内存/GPU 使用率)
     │
     ▼
自适应算法 → 根据指标计算新阈值
     │
     ▼
动态限流器 → 使用新阈值进行限流判定
  1. 采集器定期采集资源指标
  2. 算法根据当前资源使用率与目标区间的关系,计算限流阈值调整方向和幅度
  3. 动态限流器使用算法输出的阈值进行限流

PID 算法

PID (Proportional-Integral-Derivative) 是 OLC 内置的自适应算法,根据资源使用率与目标区间的偏差动态调整限流阈值。

原理简介

  • P(比例):根据当前偏差调整,偏差越大调整越大
  • I(积分):根据历史累积偏差调整,消除稳态误差
  • D(微分):根据偏差变化率调整,抑制超调

当资源使用率低于目标下限时,增加限流阈值;高于目标上限时,减少限流阈值;在目标区间内则保持不变。

参数详解

参数 默认值 说明
Kp 0.5 比例系数,控制偏差的响应强度
Ki 0 积分系数,控制累积偏差的响应强度
kd 0.5 微分系数,控制偏差变化率的响应强度
minResource 0.5 资源使用率下限(0-1),低于此值增加阈值
maxResource 0.5 资源使用率上限(0-1),高于此值减少阈值
currentUsage "localresource.memory" 动态参数,当前资源使用率的数据源
minWal 0.1 限流阈值最小比例(相对初始值)
maxWal 3.0 限流阈值最大比例(相对初始值)
delta 5 最小调整步长

currentUsage 格式<采集器名>.<属性名>,例如 "vllm.gpu_usage" 表示从 vLLM 采集器获取 gpu_usage 属性。

完整配置示例

overload-config.properties

olc.sdk.domain=my-service
olc.sdk.switch=on
olc.sdk.config.stub=jsonfile
olc.sdk.policy.update.period=6

# 采集器配置
olc.sdk.collector.active=vllm
olc.sdk.collector.capacity=10
olc.sdk.collector.sample=10
olc.sdk.collector.interval=1

olc.json

{
  "domain": "my-service",
  "rules": [
    {
      "group": {
        "name": "dynamicGroup",
        "tags": [
          {"tag": "URL", "match": "equal", "values": ["/api/chat"]},
          {"tag": "Model", "match": "equal", "values": ["gpt-4"], "share": false}
        ]
      },
      "flow": {
        "name": "dynamicFlow",
        "enabled": true,
        "flowControlMode": "concurrent",
        "policyType": "NODE",
        "timeUnit": "second",
        "timeInterval": 1,
        "rateLimit": 50,
        "burstLimit": 50,
        "calculateAlg": {
          "algName": "PID",
          "algParam": {
            "Kp": 0.5,
            "Ki": 0,
            "kd": 0.5,
            "minResource": 0.5,
            "maxResource": 0.8,
            "currentUsage": "vllm_resource.gpu_cache_usage_perc",
            "minWal": 0.1,
            "maxWal": 3.0,
            "delta": 5
          }
        }
      }
    }
  ]
}

这个配置表示:

  • 初始并发限流阈值 50
  • 当 GPU 使用率低于 50% 时,增加并发阈值(最多到 50 × 3.0 = 150)
  • 当 GPU 使用率高于 80% 时,减少并发阈值(最少到 50 × 0.1 = 5)
  • 在 50%-80% 之间时,保持当前阈值不变

调优建议

1. 设置合理的目标区间

  • minResourcemaxResource 定义了资源使用率的安全区间
  • 区间太窄会导致频繁调整,区间太宽会导致响应迟缓
  • 建议:minResource = 0.5, maxResource = 0.8(50%-80%)

2. 调整 PID 参数

  • 只用 P 控制:Kp=0.5, Ki=0, kd=0,简单但可能有稳态误差
  • P + D 控制:Kp=0.5, Ki=0, kd=0.5(默认),响应较快且抑制超调
  • P + I + D 控制:Kp=0.5, Ki=0.1, kd=0.5,消除稳态误差但需谨慎调参

3. 设置合理的阈值范围

  • minWal 防止阈值过低导致服务不可用
  • maxWal 防止阈值过高导致系统过载
  • 建议:minWal = 0.1 ~ 0.3, maxWal = 2.0 ~ 3.0

4. 调整步长

  • delta 控制每次调整的最小幅度
  • 太小会导致调整缓慢,太大会导致震荡
  • 建议:delta = 5 ~ 10

资源采集器

资源采集器定期采集系统资源指标,为自适应算法提供数据。

vLLM 采集器

vLLM 采集器从 vLLM 推理服务采集 GPU 和请求相关指标。

激活采集器

olc.sdk.collector.active=vllm

采集器参数

参数 默认值 说明
olc.sdk.collector.capacity 10 存储容量(保留的采集记录数)
olc.sdk.collector.sample 10 采样数(计算平均值时使用的样本数)
olc.sdk.collector.interval 1 采集间隔(秒)

动态限流器

动态限流器是自适应算法的运行载体,目前支持 concurrent 模式。

concurrent + PID 组合配置

动态限流器需要在 flow 配置中同时指定 flowControlModecalculateAlg

{
  "flow": {
    "flowControlMode": "concurrent",
    "rateLimit": 50,
    "calculateAlg": {
      "algName": "PID",
      "algParam": { ... }
    }
  }
}
  • rateLimit:初始并发阈值
  • calculateAlg:自适应算法配置
  • 算法输出的新阈值会替代 rateLimit 用于限流判定

阈值调整范围

算法输出受 minWalmaxWal 约束:

实际阈值 = clamp(算法输出, rateLimit × minWal, rateLimit × maxWal)

例如 rateLimit=50, minWal=0.1, maxWal=3.0

  • 最小阈值:50 × 0.1 = 5
  • 最大阈值:50 × 3.0 = 150

更多限流模式详情请参阅 限流策略使用指南