使用cgroup进行系统资源使用限制
生活随笔
收集整理的這篇文章主要介紹了
使用cgroup进行系统资源使用限制
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
環(huán)境:Centos 7 64
一、對某個進(jìn)程限制它使用cpu為50%
1、先寫一個占用cpu較高的腳本
x=0
while [ True ];do
x=$x+1
done;
2、可以看到運行后cpu使用到了100%
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 20369 root 20 0 113452 1664 1196 R 100.0 0.0 0:10.73 sh
3、創(chuàng)建控制組
mkdir /sys/fs/cgroup/cpu/foo
4、下面用cgroups控制這個進(jìn)程的cpu資源
echo 50000 > /sys/fs/cgroup/cpu/foo/cpu.cfs_quota_us #將cpu.cfs_quota_us設(shè)為50000,相對于cpu.cfs_period_us的100000是50%
echo 20369 >/sys/fs/cgroup/cpu/foo/tasks
5、我們看到大概限制到了50%左右
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 20369 root 20 0 113828 1908 1196 R 49.8 0.0 0:33.75 sh
6、cgroup控制組下還有很多對于cpu其他的一些控制
[root@foreman ~]# ls /sys/fs/cgroup/cpu/foo/ cgroup.clone_children cpuacct.usage cpu.rt_period_us notify_on_release cgroup.event_control cpuacct.usage_percpu cpu.rt_runtime_us tasks cgroup.procs cpu.cfs_period_us cpu.shares cpuacct.stat cpu.cfs_quota_us cpu.stat
ls /sys/fs/cgroup/memory/cgtest/*
cgroup.event_control #用于eventfd的接口 memory.usage_in_bytes #顯示當(dāng)前已用的內(nèi)存 memory.limit_in_bytes #設(shè)置/顯示當(dāng)前限制的內(nèi)存額度 memory.failcnt #顯示內(nèi)存使用量達(dá)到限制值的次數(shù) memory.max_usage_in_bytes #歷史內(nèi)存最大使用量 memory.soft_limit_in_bytes #設(shè)置/顯示當(dāng)前限制的內(nèi)存軟額度 memory.stat #顯示當(dāng)前cgroup的內(nèi)存使用情況 memory.use_hierarchy #設(shè)置/顯示是否將子cgroup的內(nèi)存使用情況統(tǒng)計到當(dāng)前cgroup里面 memory.force_empty #觸發(fā)系統(tǒng)立即盡可能的回收當(dāng)前cgroup中可以回收的內(nèi)存 memory.pressure_level #設(shè)置內(nèi)存壓力的通知事件,配合cgroup.event_control一起使用 memory.swappiness #設(shè)置和顯示當(dāng)前的swappiness memory.move_charge_at_immigrate #設(shè)置當(dāng)進(jìn)程移動到其他cgroup中時,它所占用的內(nèi)存是否也隨著移動過去 memory.oom_control #設(shè)置/顯示oom controls相關(guān)的配置 memory.numa_stat #顯示numa相關(guān)的內(nèi)存
寫一個內(nèi)存占用的c程序,每秒申請1MB內(nèi)存
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MB (1024 * 1024)
int main(int argc, char *argv[])
{
char *p;
int i = 0;
while(1) {
p = (char *)malloc(MB);
memset(p, 0, MB);
printf("%dM memory allocated
", ++i);
sleep(1);
}
return 0;
}
#gcc mem-allocate.c -o mem-allocate
cgroup限制內(nèi)存使用50M(強制限制 memory.limit_in_bytes)
[root@foreman cgtest]# pwd /sys/fs/cgroup/memory/cgtest [root@foreman cgtest]# echo 50M > memory.limit_in_bytes [root@foreman cgtest]# echo 0 > memory.oom_control [root@foreman cgtest]# pgrep mem-allocate 35190 [root@foreman cgtest]# echo 35190 > tasks #只對一個線程ID做限制 ,如果需要對一個線程組做限制,需要將PID放到cgroup.procs中。
這樣這個PID本身以及所衍生的進(jìn)程整體會限制在memory.limit_in_bytes中設(shè)置的大小內(nèi)存
同時包括這個PID調(diào)用所產(chǎn)生的進(jìn)程也會受到限制。想查看某個進(jìn)程所屬線程組使用如下命令
#cat /proc/<PID>/cgroup 來進(jìn)行查看
限制效果:
[root@foreman ~]# ./mem-allocate 1M memory allocated 2M memory allocated 3M memory allocated 4M memory allocated ... ... 49M memory allocated 50M memory allocated 51M memory allocated Killed
如果達(dá)到限制不想直接kill進(jìn)程,而是掛起進(jìn)程需要將oom_kill_disable 設(shè)置為1 [root@foreman cgtest]#cat memory.oom_control #默認(rèn) oom_kill_disable 0 under_oom 0 [root@foreman cgtest]# echo 1 > memory.oom_control [root@foreman cgtest]# cat memory.oom_control oom_kill_disable 1 under_oom 0
跑一個腳本使其產(chǎn)生多個子線程去瘋狂吃內(nèi)存(提前將memory.limitxxxxx設(shè)置為300MB,oom_kill 設(shè)置為0)
[root@foreman ~]# cat cgtest.sh
sleep 20
x=0
while [ True ];do
nohup /root/mem-allocate >>/root/mem.log 2>&1 &
sleep 1
proc_num=$(pgrep mem-allocate | wc -l)
if [ $proc_num -eq 50 ];then
sleep 1000000
fi
x=$(($x+1))
done;
跑起來后用systemd-cgtop查看限制情況:
#systemd-cgtop #使用此命令查看cgroup限制的資源情況 /cgtest 25 - 295.8M 通過上面可以清晰的看到tasks 25個 內(nèi)存限制到了300MB
概念理解:
就把 5678 進(jìn)程加入到了 /foo 控制組。那么 tasks 和 cgroups.procs 有什么區(qū)別呢?前面說的對“進(jìn)程”的管理限制其實不夠準(zhǔn)確。系統(tǒng)對任務(wù)調(diào)度的單位是線程。
在這里,tasks 中看到的就是線程 id。而 cgroups.procs 中是線程組 id,也就是一般所說的進(jìn)程 id 。
將一個一般的 pid 寫入到 tasks 中,只有這個 pid 對應(yīng)的線程,以及由它產(chǎn)生的其他進(jìn)程、線程會屬于這個控制組,原有的其他線程則不會。
而寫入 cgroups.procs 會把當(dāng)前所有的線程都加入進(jìn)去。如果寫入 cgroups.procs 的不是一個線程組 id,而是一個一般的線程 id,那會自動找到所對應(yīng)的線程組 id 加入進(jìn)去。
進(jìn)程在加入一個控制組后,控制組所對應(yīng)的限制會即時生效。想知道一個進(jìn)程屬于哪些控制組,可以通過 cat /proc/<pid>/cgroup 查看。 要把進(jìn)程移出控制組,把 pid 寫入到根 cgroup 的 tasks 文件即可。因為每個進(jìn)程都屬于且只屬于一個 cgroup,加入到新的 cgroup 后,原有關(guān)系也就解除了。
要刪除一個 cgroup,可以用 rmdir 刪除相應(yīng)目錄。不過在刪除前,必須先讓其中的進(jìn)程全部退出,對應(yīng)子系統(tǒng)的資源都已經(jīng)釋放,否則是無法刪除的。 前面都是通過文件系統(tǒng)訪問方式來操作 cgroups 的。實際上,也有一組命令行工具。
cgroup詳細(xì)
X
沒有英漢互譯結(jié)果
請嘗試網(wǎng)頁搜索
總結(jié)
以上是生活随笔為你收集整理的使用cgroup进行系统资源使用限制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 重学Python
- 下一篇: 安卓中bundle的使用