Google在在Android11及之后版本的LMKD中,使用了psi作为杀进程的策略,本文简单介绍下psi。

转载自使用PSI(Pressure Stall Information)监控服务器资源_Linux_gameneedless_InfoQ写作社区

1.概述

当 CPU、内存或 IO 设备争夺激烈的时候,系统会出现负载的延迟峰值、吞吐量下降,并可能触发内核的 OOM Killer。PSI(Pressure Stall Information) 字面意思就是由于资源(CPU、内存和 IO)压力造成的任务执行停顿。PSI 量化了由于硬件资源紧张造成的任务执行中断,统计了系统中任务等待硬件资源的时间。我们可以用 PSI 作为指标,来衡量硬件资源的压力情况。停顿的时间越长,说明资源面临的压力越大。

如果持续监控 PSI 指标并绘制变化曲线图,可以发现吞吐量下降与资源短缺的关系,让用户在资源变得紧张前,采取更主动的措施,例如将任务迁移到其他服务器,杀死低优先级的任务等。

这允许最大限度地提高硬件利用率,而不会牺牲工作负载的健康状况或冒着诸如 OOM 终止等重大中断的风险。

2.pressure 文件接口

CPU、内存和 IO 的压力信息导出到了 /proc/pressure/ 目录下对应的文件,你可以使用 cat 命令查询资源的压力统计信息:

$ cat /proc/pressure/cpu
some avg10=0.03 avg60=0.07 avg300=0.06 total=8723835 $ cat /proc/pressure/io
some avg10=0.00 avg60=0.00 avg300=0.00 total=56385169
full avg10=0.00 avg60=0.00 avg300=0.00 total=54915860 $ cat /proc/pressure/memory
some avg10=0.00 avg60=0.00 avg300=0.00 total=149158
full avg10=0.00 avg60=0.00 avg300=0.00 total=34054

内存和 IO 显示了两行指标:some 和 full,CPU 只有一行指标 some。关于 some 和 full 的定义下一节解释。

2.1 some 和full

some 指标说明一个或多个任务由于等待资源而被停顿的时间百分比。在下图的例子中,在最近的 60 秒内,任务 A 的运行没有停顿,而由于内存紧张,任务 B 在运行过程中花了 30 秒等待内存,则 some 的值为 50%。



some 表明了由于缺乏资源而造成至少一个任务的停顿。

full 指标表示所有的任务由于等待资源而被停顿的时间百分比。在下图的例子中,在最近的 60 秒内,任务 B 等待了 30 秒的内存,任务 A 等待了 10 秒内存,并且和任务 B 的等待时间重合。在这个重合的时间段 10 秒内,任务 A 和 任务 B 都在等待内存,结果是 some 指标为 50%,full 指标为 10/60 = 16.66%



full 表明了总吞吐量的损失,在这种状态下,所有任务都在等待资源,CPU 周期将被浪费。

请注意,some 和 full 的计算是用整个时间窗口内累计的等待时间,等待时间可以是连续的,也可能是离散的。

理解了 some 和 full 的含义,就明白了 CPU 为什么没有 full 指标,因为不可能所有的任务都同时饿死在 CPU 上,CPU 总是在执行一个任务。



3.PSI 阈值监控

用户可以向 PSI 注册触发器,在资源压力超过自定义的阈值时获得通知。一个触发器定义了特定时间窗口内最大累积停顿时间,例如,在任何 500ms 的窗口内,累计 100ms 的停顿时间会产生一个通知事件。

如何向 PSI 注册触发器呢?打开 /proc/pressure/ 目录下资源对应的 PSI 接口文件,写入想要的阈值和时间窗口,然后在打开的文件描述符上使用 select()poll() 或 epoll() 方法等待通知事件。写入 PSI 接口文件的数据格式为:

<some|full> <停顿阈值> <时间窗口>

阈值和时间窗口的单位都是微秒(us)。内核接受的窗口大小范围为 500ms 到 10 秒。

举个例子,向 /proc/pressure/io 写入 "some 500000 1000000",代表着在任何 1 秒的时间窗口内,如果一个或多个进程因为等待 IO 而造成的时间停顿超过了阈值 500ms,将触发通知事件。

当用于定义触发器的 PSI 接口文件描述符被关闭时,触发器将被取消注册。

我们通过一个例子演示触发器的使用:

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <string.h>
#include <unistd.h> int main() {
const char trig[] = "some 500000 1000000";
struct pollfd fds;
int n; fds.fd = open("/proc/pressure/io", O_RDWR | O_NONBLOCK);
if (fds.fd < 0) {
printf("/proc/pressure/io open error: %s\n",
strerror(errno));
return 1;
}
fds.events = POLLPRI; if (write(fds.fd, trig, strlen(trig) + 1) < 0) {
printf("/proc/pressure/io write error: %s\n",
strerror(errno));
return 1;
} printf("waiting for events...\n");
while (1) {
n = poll(&fds, 1, -1);
if (n < 0) {
printf("poll error: %s\n", strerror(errno));
return 1;
}
if (fds.revents & POLLERR) {
printf("got POLLERR, event source is gone\n");
return 0;
}
if (fds.revents & POLLPRI) {
printf("event triggered!\n");
} else {
printf("unknown event received: 0x%x\n", fds.revents);
return 1;
}
} return 0;
}

在服务器上编译并运行该程序,如果当前服务器比较空闲,我们会看到程序一直在等待 IO 压力超过阈值的通知:

$ sudo ./monitor
waiting for events...

我们为服务器制造点 IO 压力,生成一个 5G 大小的文件:

$ dd if=/dev/zero of=/home/mazhen/testfile bs=4096 count=1310720

再回到示例程序的运行窗口,会发现已经收到事件触发的通知:

$ sudo ./monitor
waiting for events...
event triggered!
event triggered!
event triggered!
event triggered!
event triggered!
...

4.PSI应用案例

Facebook 是因为一些实际的需求开发了 PSI。其中一个案例是为了避免内核 OOM(Out-Of-Memory) killer 的触发。

应用在申请内存的时候,如果没有足够的 free 内存,可以通过回收 Page Cache 释放内存,如果这时 free 内存还是不够,就会触发内核的 OOM Killer,挑选一个进程 kill 掉释放内存。这个过程是同步的,申请分配内存的进程一直被阻塞等待,而且内核选择 kill 掉哪个进程释放内存,用户不可控。因此,Facebook 开发了用户空间的 OOM Killer 工具 oomd

oomd 使用 PSI 阈值作为触发器,在内存压力增加到一定程度时,执行指定的动作,避免最终 OOM 的发生。oomd 作为第一道防线,确保服务器工作负载的健康,并能自定义复杂的清除策略,这些都是内核做不到的。

5.cgroup v2

当打开kernel的配置CONFIG_CGROUP=y且挂载cgroup2文件系统的时候,就可以跟踪cgroup 内任务的 PSI,这样就可以知道容器内 CPU、内存和 IO 的真实压力情况,进行更精细化的容器调度,在资源利用率最大化的同时保证任务的延迟和吞吐量。

每个子目录中包含cpu.pressurememory.pressure, 和 io.pressure files,格式与/proc/pressure/文件一致。

Linux PSI--Pressure Stall Information的更多相关文章

  1. linux虚拟系统determining IP information for eth0...failed

    这几天学习老男孩Linux运维 其中有一节视频进行连接网络时出现: 上网搜了很多方法,包括:向如下三个文件中添加如下代码 check_link_down() { return 1; } (1)/etc ...

  2. openEuler 20.03/21.03 - 华为欧拉开源版(CentOS 8 华为版开源版)下载

    开始 openEuler 之旅吧 openEuler 通过社区合作,打造创新平台,构建支持多处理架构.统一和开放的操作系统,推动软硬件应用生态繁荣发展. 好玩的活动停不下来 openEuler 社区不 ...

  3. K8s如何启用cgroup2支持?

    什么是 cgroup ️Reference: control groups(控制组),通常被称为cgroup,是Linux内核的一项功能.它允许将进程组织成分层的组,然后限制和监控各种资源的使用. 内 ...

  4. 《Linux内核设计与实现》读书笔记(十三)- 虚拟文件系统

    虚拟文件系统(VFS)是linux内核和具体I/O设备之间的封装的一层共通访问接口,通过这层接口,linux内核可以以同一的方式访问各种I/O设备. 虚拟文件系统本身是linux内核的一部分,是纯软件 ...

  5. Linux Communication Mechanism Summarize

    目录 . Linux通信机制分类简介 . 控制机制 0x1: 竞态条件 0x2: 临界区 . Inter-Process Communication (IPC) mechanisms: 进程间通信机制 ...

  6. Linux基础--用户和组管理

    1.账号管理相关文件 1)/etc/passwd    每一行都代表一个账号,有几行就代表有几个账号在你的系统中,不过需要特别留意的是,里头很多账号本来就是系统中必须要的,我们可以简称他为系统账号, ...

  7. Anatomy of the Linux kernel--转

    ref:http://www.ibm.com/developerworks/linux/library/l-linux-kernel/?S_TACT=105AGX52&S_CMP=cn-a-l ...

  8. Linux虚拟文件系统VFS解决

    参考<Linux内核设计与实现> 虚拟文件系统(VFS)它是linux核心和详细I/O一个普通的访问接口之间的包装设备,通过这层界面,linux内核能够以同一的方式訪问各种I/O设备. 虚 ...

  9. Linux下 USB设备驱动分析(原创)

    之前做过STM32的usb HID复合设备,闲来看看linux下USB设备驱动是怎么一回事, 参考资料基于韦东山JZ2440开发板,以下,有错误欢迎指出. 1.准备知识 1.1USB相关概念: USB ...

  10. 12 Linux Which Command, Whatis Command, Whereis Command Examples

    This Linux tutorial will explain the three "W" commands. The three "W"s are what ...

随机推荐

  1. scratch源码下载 | 超大太空游戏【80MB】

    按方向键或AWSD键控制角色移动,按空格键或X键攻击. 程序超级大,共80MB,耐心等待加载. 截图: 点击下载源码 更多源码访问:小虎鲸scratch资源站

  2. perf 性能分析工具

    perf 性能分析工具 perf topperf recordperf reportperf listperf stat perf top -p <pid> 例如查看redis进程的内核调 ...

  3. 15、Spring之基于xml的声明式事务

    阅读本文前,建议先阅读Spring之基于注解的声明式事务 15.1.环境搭建 创建名为spring_transaction_xml的新module,过程参考13.1节 15.1.1.配置打包方式和依赖 ...

  4. 【Vue2】Router 路由

    1.什么是单页面应用程序 单页面应用程序(英文名: Single Page Application)简称SPA, 顾名思义,指的是一个Web网站中只有唯一-的一-个HTML页面, 所有的功能与交互都在 ...

  5. 【SVN】提交失败报错

    SVN提交失败: 最后信息是提示 请输入日志消息,至少需要20个字符,提交终止 问题原因是: 提交的时候不要把提交信息换行来写,SVN只会读取第一行内容 如果消息没有问题还提交失败,可能是文件因为提交 ...

  6. 【Java-GUI】06 绘图 Part2 位图处理

    绘画程序案例: 原视频排错找了半天,原来是变量名的问题 package cn.dzz; import java.awt.*; import java.awt.event.*; import java. ...

  7. 【Spring-Security】Re09 CSFR处理

    一.CSRF: CSRF 全称 Cross Site Request Forgery 跨站请求伪造 又称为OneClick Attack & SessionRiding 是非法请求访问,通过伪 ...

  8. 国产计算框架mindspore在gpu环境下1.3.0版本的分布式计算组件安装 ——(openmpi 和 nccl 的安装,配置,示例代码的运行)

    前文已经给出1.3.0gpu版本的编译及安装,本文在此基础上进行分布式组件的安装,前文信息参看: 国产计算框架mindspore在gpu环境下编译分支r1.3,使用suod权限成功编译并安装,成功运行 ...

  9. 【转载】 pytorch锁死在dataloader(训练时卡死)

    版权声明:本文为CSDN博主「Totoro-wen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/qq_325 ...

  10. LemurBrowser狐猴浏览器:支持插件扩展、内置免费AI工具的移动端浏览器

    如何选择一款合适的浏览器? 在这个数字化时代,浏览器作为互联网的入口.然而,选择一款合适的浏览器却并不容易. 注释:狐猴浏览器是浏览器新标签页插件Wetab提供的支持在移动端安装插件,内置免费AI工具 ...