![对于 CPU 和 IO 具有不同进程优先级的用例?](https://linux22.com/image/584542/%E5%AF%B9%E4%BA%8E%20CPU%20%E5%92%8C%20IO%20%E5%85%B7%E6%9C%89%E4%B8%8D%E5%90%8C%E8%BF%9B%E7%A8%8B%E4%BC%98%E5%85%88%E7%BA%A7%E7%9A%84%E7%94%A8%E4%BE%8B%EF%BC%9F.png)
Linux 进程可以有不同的 CPU 和 IO 优先级(nice 和 ionice)。
为什么需要有不同的 CPU 和 IO 优先级?
它们之间的区别在现实世界中有实际用途吗?
您发现哪些实际用例需要不同的 CPU 和 IO 优先级?例如高于正常 CPU 优先级但低于正常 IO 优先级,反之亦然。
答案1
“nice”的默认行为是当 niceness 发生变化时调整应用程序的“io”优先级。
当然,一切都取决于你的工作量,但任何操作系统的一个关键方面是它如何分配资源,以及如何处理争执。
理解 niceness 的作用实际上很重要,因为当面临来自竞争进程的负载时,操作系统的行为方式可能会对其余工作负载产生影响。
争用是衡量不同应用程序如何竞争同一资源(如 CPU)的标准。
处理负载
自从引入完全公平调度程序以来,nice 仅仅是每个进程的“权重”子句的前端。可以在 proc 中查看。
$ cat /proc/self/sched
---------------------------------------------------------
...
se.load.weight : 1024
...
改变善良程度只会改变体重:
$ nice -n 5 cat /proc/self/sched
---------------------------------------------------------
...
se.load.weight : 335
...
CPU 争用度量由完全公平的调度算法完成。每个应用程序都分配有一个“权重”值,如果存在 CPU 时间争用,则通过汇总所有争用 CPU 时间的处理,并根据它们的权重值为它们分配最低的公共 CPU 时间,从而在进程之间分配时间。
如果我有 3 个应用程序都想使用 CPU 时间,默认情况下它们会收到 1024 作为正常权重。如果我有一个进程的 nice 值为 +5(如上所示),则所有三个权重总计为 2383,因此如果所有 3 个进程都在请求 CPU,则 nice 进程将在给定的一秒钟内获得大约 15% 的 CPU 时间。
为什么需要有不同的 CPU 和 IO 优先级?
优良性实际上只是在研究系统负载下该做什么,即操作系统如何根据需要的因素在竞争进程之间分配时间。
这对您有何影响或与您有何关联,取决于不同应用程序之间的交付优先级以及每个应用程序应有的交付时间。
善良真的只会某物当你的系统处于负载状态时(需要处理的东西比 CPU 或磁盘所能处理的要多)。它只是指示内核如何在这些情况下分配资源。
它们之间的区别在现实世界中有实际用途吗?
如果您有多个竞争进程或要完成的工作超出了 CPU 的能力范围,niceness 可以为您提供一些相对稳定的保证,确定哪些工作先完成。如果您要生成一份报告,而该报告应在另一份报告完成之前交付,那么这可能对您很重要。
在桌面系统上,友好度可能更为重要。某些应用程序具有实时行为,因此在加载期间更频繁地唤醒它们可防止数据过时。例如,Pulseaudio 就属于此类。
其他应用程序可能需要为依赖的应用程序分配工作。例如,许多 Apache 请求发送到 SQL 服务器(例如 MySQL)可能会长时间阻塞,因为 SQL 处理速度不够快,因为——比如说,其他一些报告正在争夺 CPU 时间。因此,不仅 SQL 停滞不前,Apache 也是如此。SQL 有时会在这里受到影响,因为通常工作线程比 Apache 线程少得多,它们作为一个组竞争以获得调度程序的更有利的权重,因此为 SQL 提供更多的 CPU 时间可以使情况更加平衡。
UpdateDB(一个索引文件的程序)在深夜运行,占用大量磁盘空间。降低其 IO 调度优先级可能会很有用,这样当时其他应用程序的优先级就会高于那些在顺序上不那么重要的应用程序。
您发现哪些实际用例需要不同的 CPU 和 IO 优先级?
很少。友善是一种尽最大努力的方法。根据经验,我不太关心应用程序的性能, 更多的他们有多糟糕可以执行。这听起来可能有点倒退,但我需要满足服务交付保证,这对我来说更为重要。
我希望有信心说“即使在糟糕的一天,你的工作也会在某段时间内完成”。如果进展更快,那只是额外的奖励。
我通常首先制定约定的规范,例如:
- 保证所有Web应用程序在0.3秒内完成请求。
- 系统上的所有SQL请求都保证在0.1秒内完成。
- Web 应用程序应处理不超过 50 IOPS 并传送 1k 个文件。
- Web应用程序的内存占用总计不超过250Mb。
并列出需要满足的要求,例如:
- 所有网络请求应在 0.05 秒内完成。
- 所有 SQL 请求应在 0.02 秒内完成。
- 应该有足够的内存处理所有请求。
- 应满足 IO 要求。
如果规范属实,那么我无需进行虚拟化就可以实现这些目标,而是使用效率更高的控制组方法。
只要应用程序在指定的范围内运行,控制组就可以让我为资源分配提供相当可靠的服务级别保证。这意味着即使在负载过大的系统中,我也可以保证相关应用程序的资源可用性,并保证同一台机器上其他应用程序的空间!
如果我们以 CPU 和 IO 为例。我设置了满足这些要求的限制:
# cd /sys/fs/cgroup/blkio/apache
# echo "253:0 100" >blkio.throttle.read_iops_device
# echo "253:0 50" >blkio.throttle.write_iops_device
# echo "253:0 102400" >blkio.throttle.read_bps_device
因此,读取 100k 字节需要 100 iops。
# cd /sys/fs/cgroup/cpu/apache
# echo 1000000 >cpu.cfs_period_us
# echo 60000 >cpu.cfs_quota_us
在 1 秒的时间段内,提供 0.06 秒的 CPU。
# cd /sys/fs/cgroup/cpu/sql
# echo 1000000 >cpu.cfs_period_us
# echo 20000 >cpu.cfs_quota_us
在 1 秒的时间段内,提供 0.02 秒的 CPU。
只要其他竞争的 cgroups 不做任何愚蠢的事情,负载就不会对我的服务交付产生太大影响,因为我知道每个应用程序对 CPU 的使用情况如何。
此类对照组仍然尽最大努力,但是它们对这种努力的控制远比 niceness 和 ioniceness 要多。