KEDA 想扩到 20 个副本,不等于现在就有 20 份可用算力

本文剖析KEDA与Kubernetes HPA协同扩缩容时的关键瓶颈:从指标触发到真正可服务存在多阶段延迟,包括调度、Pod启动、模型加载及就绪探针校验。强调不能将desired副本数等同于可用算力,需区分scheduled/ready/可服务状态;指出GPU场景下镜像拉取、模型加载、竞价节点通知不确定性等独立瓶颈,并建议将‘扩不起来’纳入降级策略,通过持续监控目标与就绪容量差、排队年龄、启动耗时等指标优化容量规划。

扩容目标与就绪容量之间的差距

队列变长,指标触发,控制器提高副本数,调度器找到节点,进程启动,模型加载,探针就绪,最后才开始接流量。这是一条链。把第一步发生的时间写成“扩容完成耗时”,会在大促时高估可用容量。

两个循环和一个容易漏掉的等待段

KEDA ScaledObject 文档区分轮询间隔以及 HPA 参与的扩缩阶段。Kubernetes HPA 文档也说明自动扩缩是周期控制,默认控制循环间隔为 15 秒。写一个更小的 pollingInterval,不代表每隔这么久就能得到一批已经加载模型的 GPU Pod。

还要区分 desired、scheduled、ready 和真正可服务的吞吐。预热探针若只检查 HTTP 端口而不检查模型装载,ready 也会过早乐观。

目标副本经过调度预热后才变成服务容量

一个容量估算里应保留哪些量

下面只算“活跃任务加排队任务”的粗略副本目标,不模拟 Kubernetes。所有输入是教学数字,不是测量值。

public class Demo {
    static int desired(long queued, long active, int perReplica,
                       int min, int max) {
        if (queued < 0 || active < 0 || perReplica <= 0 || min < 0 || max < min) {
            throw new IllegalArgumentException();
        }
        long work = Math.addExact(queued, active);
        long units = work / perReplica + (work % perReplica == 0 ? 0 : 1);
        return (int)Math.max(min, Math.min(max, units));
    }
    static int gap(int desired, int ready) {
        if (ready < 0) throw new IllegalArgumentException();
        return Math.max(0, desired - ready);
    }
    public static void main(String[] args) {
        int target = desired(65, 15, 4, 2, 30);
        if (target != 20 || gap(target, 8) != 12) throw new AssertionError();
        if (desired(0, 0, 4, 2, 30) != 2) throw new AssertionError();
        if (desired(10000, 0, 4, 2, 30) != 30) throw new AssertionError();
        if (gap(10, 12) != 0) throw new AssertionError();
        System.out.println("target=20, ready=8, pending capacity gap=12");
    }
}

保存为 Demo.java 后运行 javac --release 11 Demo.java、java Demo。模型请求长短不同,四个请求未必耗费同样算力。实际指标可能要改成排队 Token、等待时间分位数或模型分组工作量,并通过压测标定,而不是直接复制 perReplica=4。

把“扩不起来”也纳入降级

持续记录目标与就绪容量差、最老排队年龄、启动阶段耗时和扩容失败原因。指标过期时,不应因为读到旧的空队列就突然缩容。GPU 配额、镜像拉取和模型文件读取都可能成为独立瓶颈。

竞价节点还需要更保守的退出方案。AWS Spot 通知文档说明通知是尽力而为,休眠场景也不是统一的两分钟预留。不能把收到通知当成唯一的状态保存入口。

本文没有接入 KEDA、Kubernetes 或真实 GPU。算式只帮助暴露容量缺口;需要靠环境中的启动数据决定保底副本、排队上限和拒绝策略。

本地运行环境为 Java/javac 12.0.1,使用 --release 11 编译并执行了文中的检查;没有安装新依赖。该结果只覆盖示例列出的逻辑,不代表真实模型、浏览器或生产链路已经验证。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值