一、调度问题概述

大家好,我是这次课程的主讲。今天咱们聊聊任务调度——这个看似基础、实则门道极深的话题。

说实话,我刚开始做系统设计那会儿,觉得调度不就是排个队嘛,谁先来谁先走。直到有一次,我在一个实时数据处理项目里栽了跟头——任务堆积、资源争抢、系统直接卡死。嗯,从那以后我才真正重视起调度问题。

1.1 什么是任务调度?

任务调度,说白了就是回答三个问题:谁先做?谁后做?谁和谁一起做?

你想想看,一个系统里同时来了几十个任务,CPU就那么几颗,内存就那么点,磁盘IO还有瓶颈。怎么安排这些任务,才能让系统跑得又快又稳?这就是调度要干的事。

核心定义:任务调度是指在有限的计算资源下,按照某种策略对任务进行排序和分配,以达成特定的优化目标。

1.2 任务调度的分类

调度问题可以从两个维度来切分。我个人习惯这样分:

按机器数量:单机 vs 多机

类型 特点 典型场景
单机调度 一台机器处理所有任务 个人电脑、嵌入式设备
多机调度 多台机器协同处理 数据中心、集群计算

单机调度相对简单,但别小看它。我在做嵌入式系统时,单核CPU上跑着十几个实时任务,优先级稍微设错,系统就崩了。

多机调度就复杂多了。你得考虑任务怎么拆分、数据怎么同步、机器挂了怎么办。我记得有个分布式训练的项目,8张GPU卡,调度策略没写好,结果4张卡在干活,另外4张在空转——资源浪费得一塌糊涂。

按决策时机:在线 vs 离线

  • 离线调度:所有任务信息提前知道。比如你有一批计算任务,每个任务跑多久、需要多少内存,事先都清楚。这时候可以全局规划,找到最优解。
  • 在线调度:任务一个接一个来,你没法预知后面会来什么。比如Web服务器的请求处理,你永远不知道下一秒有多少用户涌进来。

我的经验:实际项目中,纯离线或纯在线的情况很少。大部分是「半在线」——部分任务信息已知,部分未知。这时候需要混合策略,我一般会先做离线预分配,再留出20%的缓冲资源应对突发。

1.3 核心优化目标

调度不是瞎排,得有目标。常见的优化目标有三个:

目标一:最小化完工时间

也叫makespan,就是所有任务从开始到全部完成的总时间。这个指标最直观——用户等得越久,体验越差。

举个例子,你有一批数据要处理,单机跑要10小时,用4台机器并行跑,理论上2.5小时就能搞定。但实际中因为任务拆分、通信开销,可能得3.5小时。调度算法的目标就是让这个时间尽可能接近理论值。

目标二:最大化资源利用率

资源利用率 = 实际使用资源 / 总资源。这个指标老板们最爱看——花了钱买的服务器,不能闲着。

但这里有个坑:资源利用率不是越高越好。我曾经在一个项目中,把CPU利用率压到了95%以上,结果系统频繁抖动,任务响应时间反而变长了。为什么?因为资源用得太满,没有余量应对突发波动。

避坑指南:我曾经把资源利用率目标设到98%,结果系统频繁触发OOM killer。后来我学乖了,一般留10%-15%的余量。资源利用率控制在80%-85%是比较健康的区间。

目标三:兼顾公平性

这个在在线调度里特别重要。你不能让一个大任务把资源全占了,小任务一直饿死。常见的做法是加权公平队列(WFQ),给每个任务分配权重,按比例分享资源。

1.4 知识体系总览

下面这张图,是我梳理的调度问题知识框架。你可以把它当作整个章节的地图:

任务调度问题 按机器数量 按决策时机 优化目标 单机调度 多机调度 离线调度 在线调度 最小化完工时间 资源利用率 FCFS / SJF / RR Min-Min / Max-Min 贪心 / 动态规划 EDF / 优先级 负载均衡算法 ... 核心挑战:在多个目标之间找到平衡点 没有银弹,只有最适合场景的方案

1.5 一个真实案例

最后分享一个我踩过的坑。之前做一个视频转码平台,用户上传视频后,系统要转成多种分辨率。一开始我用了最简单的FCFS(先来先服务),结果呢?

  • 一个4K的大视频来了,占着GPU转了一个小时
  • 后面一堆短视频排着队,用户等得直骂娘
  • 资源利用率倒是挺高,但用户体验极差

后来我改成了优先级调度——短视频优先级高,长视频优先级低。同时加了个超时机制,长视频如果转太久,就拆成多个小段并行转。效果立竿见影,用户满意度从60%升到了92%。

小结一下:调度没有标准答案,关键是要理解你的业务场景。是追求吞吐量?还是追求响应时间?还是两者都要?想清楚目标,再选策略。

好了,这一章就到这里。调度问题的框架已经搭好了,后面我们会一步步深入每个子问题。

可可精品资料库