linux進程調度cgroup原理及測試

不僅linux下的容器docker就是基於cgroup,很多虛擬機為了分配資源也是基於cgroup。

下面細說下cgroup的來龍去脈。

完全公平調度演算法會儘力在進程之間保證公平。如果有4個優先順序相同的進程,CFS會努力讓每個

進程獲得的CPU時間為25%,以確保公平,如下所示。

表面看每個進程都被進程調度器公平對待了,即4個進程每個都獲得了25%的CPU時間。但是其中的用戶B並沒有得到公平的對待。我們將情況考慮得再極端一點:系統上存在50個進程,其中49個都屬於用戶A,而用戶B只有1個進程。那麼對於用戶B而言,它只能使用2%的CPU資源,這顯然是不公平的。

比較合理的做法是,首先確保組間的公平,然後才是組內進程之間的公平,如下所示:

Advertisements

Linux內核實現了cgroups(controlgroups的縮寫)功能,該功能用來限制、記錄和隔離一個進程組群所使用的物理資源(如CPU、內存、磁碟IO、網路等)。為了管理不同的資源,cgroups提供了一系列子系統,現在介紹的cpu和cpuset等都屬於cgroups的子系統。cpu子系統只用於限制進程的CPU使用率。接下來介紹如何使用cgroups的cpu子系統來創建組(taskgroup)及按組來分配CPU資源。

首先需要在配置文件/etc/cgconfig.conf中添加以下內容:

mount {

#格式是 子系統 = 掛載點

cpu = /mnt/cgroups/cpu;

cpuacct = /mnt/cgroups/cpu;

Advertisements

}

然後掛載和安裝cgroup文件系統,掛載時需要啟用CPU資源控制:

mount -t cgroup -o cpu,cpuacct cpu /mnt/cgroups/cpu

掛載之後,掛載點目錄/mnt/cgroups/cpu下已經有如下文件:

在/mnt/cgroups/cpu目錄下創建兩個目錄:GroupA和GroupB,這樣就會創建兩個進程組群。

mkdir /mnt/cgroups/cpu/GroupA

mkdir /mnt/cgroups/cpu/GroupB

目錄創建完畢后,可以看到/cgroup/cpu/GroupA和/cgroup/cpu/GroupB目錄下都已經存在了很多文件,如圖所示:

只需要向GroupA的tasks文件中寫入進程ID,該進程就成為了GroupA的成員,當該進程創建子進程時,子進程也會自動成為GroupA中的成員。下面進行一個簡單的實驗,使用cgroups的cpu子系統來實現分組之間公平地使用CPU資源。

首先打開一個終端,將shell進程的PID寫入GroupA的tasks文件中,

echo $$ > /mnt/cgroups/cpu/GroupA/tasks

然後在該終端上通過stress命令(可用yum -y installstress安裝),喚起4個進程執行死循環,消耗CPU資源。

stress -c 4

如圖所示:

由於stress命令會成為shell的子進程,所以也會在GroupA中,因為當該進程創建子進程時,子進程也會自動成為父進程所在Group中的成員。

查看與stress相關的命令:

此時可以看到,/cgroup/cpu/GroupA/tasks中,已經存在多個進程,它們是bash進程和stress進程。其中stress進程有5個:1個幾乎不消耗CPU資源的管理進程和4個消耗大量CPU資源的死循環進程。因為該shell中除了stress之外,並無需要消耗CPU的其他進程,所以4個stress進程消耗了幾乎所有它能使用的CPU資源。

然後在另一個窗口,把當前shell的pid寫入GroupB的tasks,然後執行stress -c 2,

再次觀察

本機一共4個cpu,那麼cpu資源應該是400%,如果沒有cgroup,一共6個stress進程,那麼每個stress進程應該佔用66.6%的資源。有了cgroup,cpu資源就在兩個組之間分配,GroupA一共佔2個cpu,共200%的資源,4個stress進程,故每個進程占約50%的資源。而GroupB也要佔2個cpu,共200的cpu資源,組內有2個stress進程,故每個進程佔100%的資源,真正做到了兼顧組間公平和組內公平。

在完全公平調度域內,進程有優先順序,高優先順序的進程享有更多的CPU時間。能否讓組與組之間也存在優先順序差異,比如GroupB佔用的CPU時間是GroupA的2倍?

答案是肯定的。每一個組內都有cpu.shares文件,cpu.shares的值默認是1024,和普通進程默認優先順序對應的權重(NICE_0_LOAD)是一樣的。這說明進程調度會將整個組看成是1個普通進程來分配CPU資源。

下面調整GroupB的cpu.shares的值,將其調整為2048(GroupA cpu.shares值的兩倍),

然後重複上面的實驗,請自行測試。

Advertisements

你可能會喜歡