2. 资源管理基础
各位同学,咱们今天聊聊资源管理。说白了,就是操作系统怎么把 CPU、内存、I/O 这些硬件资源,合理地分给各个任务。
我刚开始做系统开发时,总觉得资源是无限的。直到有一次线上服务突然卡死,查了半天才发现是内存泄漏。嗯,从那以后我就明白了——资源管理,是调度系统的地基。
CPU 资源模型
CPU 是计算机的大脑。但大脑一次只能想一件事,对吧?CPU 也一样,一个核心在某一时刻只能执行一个任务。
那怎么实现多任务呢?靠的是时间片轮转。
核心概念:CPU 把时间切成一个个小片,每个任务轮流用。切换得够快,用户就觉得是同时在运行。
我个人习惯把 CPU 资源抽象成三个维度:
- 计算能力:每秒能执行多少指令,单位是 MIPS 或 FLOPS
- 时间片:每个任务能连续占用 CPU 的时间长度
- 优先级:决定谁先拿到 CPU 时间片
举个例子,一个 4 核 CPU,每个核主频 2.0GHz。理论上每秒能执行 80 亿条指令。但实际能用到多少?我告诉你,能有 60% 就不错了。为什么?因为上下文切换、缓存缺失、中断处理,都在吃性能。
我的经验:在项目中,我习惯用 top 命令看 CPU 的 us、sy、wa、id 四个值。us 高说明用户程序在忙,sy 高说明系统调用太多,wa 高说明磁盘 I/O 在拖后腿。对症下药,效率翻倍。
内存资源模型
内存是程序的舞台。程序要运行,代码和数据都得加载到内存里。
内存模型其实就三个关键点:
- 容量:能装多少数据,单位是 GB
- 带宽:每秒能读写多少数据,单位是 GB/s
- 延迟:从发出请求到拿到数据,需要多少纳秒
你想想看,CPU 每秒能处理几十亿条指令,但内存的延迟是几十纳秒。这中间的差距,全靠缓存来填。
避坑指南:我曾经遇到过一个任务调度系统,内存分配策略是「谁申请就给谁」。结果某个任务疯狂申请内存,把其他任务都挤死了。后来我加上了内存上限和 OOM Killer 策略,才算稳住。
内存的抽象模型,我一般用这张图来理解:
I/O 资源模型
I/O 是系统的慢速环节。磁盘、网卡、键盘、鼠标,都算 I/O 设备。
I/O 模型的核心指标就两个:
| 指标 | 含义 | 典型值 | 我的备注 |
|---|---|---|---|
| IOPS | 每秒能完成多少次 I/O 操作 | HDD: 100-200 / SSD: 10万+ | 随机读写时差距巨大 |
| 吞吐量 | 每秒能传输多少数据 | SATA: 600MB/s / NVMe: 3-7GB/s | 顺序读写时看这个 |
| 延迟 | 一次 I/O 请求从发出到完成的时间 | HDD: 5-10ms / SSD: 0.1ms | 这是调优的关键 |
注意:I/O 是任务调度中最容易忽略的瓶颈。我曾经优化过一个批处理系统,CPU 利用率只有 20%,但任务就是跑不快。一查,磁盘 IOPS 打满了,所有任务都在等磁盘。后来改成异步 I/O + 预读,性能直接翻倍。
资源抽象与虚拟化
为什么要做资源抽象?说白了,就是让上层不用关心底层细节。
你写代码时,不用管数据到底存在磁盘的哪个扇区。操作系统帮你抽象成了文件。这就是抽象的力量。
虚拟化更进一步。它把一份物理资源,变成多份虚拟资源。每个虚拟机都觉得自己独占了一台物理机。
三种常见的虚拟化方式:
- 全虚拟化:完全模拟硬件,客户机不用改。比如 VMware、KVM
- 半虚拟化:客户机知道自己被虚拟化了,需要修改驱动。比如 Xen
- 容器化:共享宿主机内核,只做资源隔离。比如 Docker
我个人最常用的是容器化。为什么?因为轻量。启动一个容器只要毫秒级,启动一个虚拟机要几十秒。在任务调度场景下,容器化的弹性伸缩能力太香了。
我的建议:如果你在做任务调度系统,优先考虑容器化。但要注意,容器不是完全隔离的。内核漏洞、资源竞争,还是可能影响到其他容器。关键任务建议用虚拟机。
资源抽象的核心逻辑
我把资源抽象总结成一句话:把物理资源池化,按需分配,隔离使用。
来看这张流程图:
嗯,这里要注意。资源抽象不是万能的。抽象层会带来性能损耗。虚拟化大概有 5%-10% 的性能损失。容器化损耗小一些,大概 1%-3%。
所以,在做架构设计时,你要权衡:是要极致的性能,还是要灵活的调度?
总结一下:
- CPU 资源看时间片和优先级
- 内存资源看容量、带宽、延迟
- I/O 资源看 IOPS、吞吐量、延迟
- 资源抽象让上层不用关心底层
- 虚拟化把一份物理资源变成多份虚拟资源
好了,这一章的内容就到这里。资源管理是调度系统的基础,把这些概念吃透了,后面讲任务调度策略时,你就能理解为什么有些策略好,有些策略不好。