Pressure Stall Information
壓力失速資訊
Date: April, 2018
Author: Johannes Weiner [email protected]
當CPU、MEM或者IO設備被爭奪時,作業負載就會經受延遲增加,吞吐量損失和運行時被OOM殺死的風險,
如果沒有資源競爭的精確測量,用戶被迫或者安全操作然后充分利用硬體資源,或者賭上一把然后頻繁遭遇到程式中斷的后果,
PSI功能識別和量化這些中斷,他們由大量資源處理引起的、復雜作業負載中的時間影響到的,或者甚至由整個系統造成的,
有一種由資源稀缺引起的生產效率損失的精確測量方法,可以幫助大作業負載下的用戶來根據作業量需求做硬體化或者提供硬體化,
因為PSI實時收集這些資訊,系統能使用這些技術進行動態管理,例如負載調度、遷移任務到其他的系統或者資料中心、或者策略性地暫停或者殺死低優先級或可重啟的批處理任務,
這個特性允許最大化硬體利用率而不用犧牲作業負載健康或者承擔OOM殺死的中斷風險,
壓力介面
每種資源的壓力資訊通過/proc/pressure/下的檔案(cpu、memory、io)匯出來,
格式如下:
some avg10=0.00 avg60=0.00 avg300=0.00 total=0
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
"some"行表示至少有一些任務在給定資源上失速的時間份額,
"full"行表示所有非空閑任務在給定資源上同時失速的時間份額,在這個狀態下,實際的CPU周期將會浪費掉,花費了額外時間的作業負載被認為受到了沖擊,這會對性能有嚴重的影響,一些任務正在失速但是CPU仍然在做大量的作業,識別出這種狀態是很有用的,花費在這些失速狀態下的時間可以分別跟蹤并匯入到“full”平均值中,
CPU full沒有在系統中定義,但是從5.13版本已經開始報告了,為了后向兼容,它被設定為0,
百分比跟蹤的是最近10/60/300秒視窗趨勢,可以跟蹤短期和中長期的趨勢,總的絕對失速時間(us)用來探測延遲增加,它不需要平均時間或者時間視窗的平均趨勢,
壓力閾的監測
用戶可以注冊觸發器然,當資源壓力超過特定閾值時使用poll()來喚醒,
觸發器描述了整個特定時間視窗內的最大累計失速時間,例如在任何500ms視窗內,總的失速時間達100ms就產生一個喚醒事件,
要注冊觸發器,用戶必須打開/proc/pressure下的PSI介面檔案,寫入期望的閾值和時間視窗,打開檔案的描述符應該使用select()、poll() 或者 epoll()來等待觸發器,使用下面的格式:
<some|full> <stall amount in us> <time window in us>
舉個例子,寫入“some 150000 1000000”到/proc/pressure/memory,將會加入150ms的閾值來做1秒時間視窗內的memory失速測量,寫入“full 50000 1000000”到/proc/pressure/io將加入50ms閾值來做1秒時間視窗內的full io失速測量.
觸發器可以設定多個PSI測量單位,也可以為相同的PSI測量單位定義多個觸發器,然而每個觸發器需要獨立的檔案描述符來各自地輪詢,因而當相同的psi介面檔案正在打開,每個觸發器的open()系統呼叫也可以打開它,對已經存在psi觸發器的檔案描述符的寫操作會觸發EBUSY失敗,
只有當系統進入失速狀態監視器才會激活,退出失速狀態就會去活,當系統在失速狀態,psi信號增長是以每個跟蹤視窗的十倍比率監測的,
內核接受視窗大小的范圍500ms~10s,因此最小監測更新間隔是50ms,最大是1s,設定最小限制是為了防止跟隨后的輪詢產生時間疊壓,選擇最大限制是因為更高的監視視窗幾乎是不需要的,可以用psi平均值來代替,
當激活之后,psi監視器在跟蹤視窗期間會保持激活狀態,避免當系統進出失速狀態時反復的激活/去活,
給用戶空間的通知頻率限制為每個跟蹤視窗一次,,
觸發器檔案描述符被關閉時,觸發器會解除注冊,
用戶空間監視器使用示例
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <string.h>
#include <unistd.h>
/*
* Monitor memory partial stall with 1s tracking window size
* and 150ms threshold.
*/
int main() {
const char trig[] = "some 150000 1000000";
struct pollfd fds;
int n;
fds.fd = open("/proc/pressure/memory", O_RDWR | O_NONBLOCK);
if (fds.fd < 0) {
printf("/proc/pressure/memory open error: %s\n",
strerror(errno));
return 1;
}
fds.events = POLLPRI;
if (write(fds.fd, trig, strlen(trig) + 1) < 0) {
printf("/proc/pressure/memory 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;
}
Cgroup2介面
系統內核配置了CONFIG_CGROUP=y,cgroup2檔案系統已被掛載,壓力失速資訊也用來跟蹤cgroup中的分組任務,cgroupfs掛載點下的每個子目錄
包含cpu.pressure、memory.pressure和io.pressure檔案,他們的格式跟/proc/pressure一樣,
每個cgroup的psi監視器可以跟系統級的定義和使用方式完全一樣,
英文原文:
https://www.kernel.org/doc/html/latest/accounting/psi.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/491008.html
標籤:其他
下一篇:jQuery全域活動非活動按鈕
