Linux Cgroup系列(05):限制cgroup的CPU使用(subsystem之cpu)

在cgroup裏面,跟CPU相關的子系統有cpusetscpuacctcpuhtml

其中cpuset主要用於設置CPU的親和性,能夠限制cgroup中的進程只能在指定的CPU上運行,或者不能在指定的CPU上運行,同時cpuset還能設置內存的親和性。設置親和性通常只在比較特殊的狀況才用得着,因此這裏不作介紹。node

cpuacct包含當前cgroup所使用的CPU的統計信息,信息量較少,有興趣能夠去看看它的文檔,這裏不作介紹。shell

本篇只介紹cpu子系統,包括怎麼限制cgroup的CPU使用上限及相對於其它cgroup的相對值。ubuntu

本篇全部例子都在ubuntu-server-x86_64 16.04下執行經過bash

建立子cgroup

在ubuntu下,systemd已經幫咱們mount好了cpu子系統,咱們只須要在相應的目錄下建立子目錄就能夠了ide

#從這裏的輸出能夠看到,cpuset被掛載在了/sys/fs/cgroup/cpuset,
#而cpu和cpuacct一塊兒掛載到了/sys/fs/cgroup/cpu,cpuacct下面
dev@ubuntu:~$ mount|grep cpu
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)

#進入/sys/fs/cgroup/cpu,cpuacct並建立子cgroup
dev@ubuntu:~$ cd /sys/fs/cgroup/cpu,cpuacct
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct$ sudo mkdir test
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct$ cd test
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ ls
cgroup.clone_children  cpuacct.stat   cpuacct.usage_percpu  cpu.cfs_quota_us  cpu.stat           tasks
cgroup.procs           cpuacct.usage  cpu.cfs_period_us     cpu.shares        notify_on_release

除了cgroup裏面通用的cgroup.clone_children、tasks、cgroup.procs、notify_on_release這幾個文件外,以cpuacct.開頭的文件跟cpuacct子系統有關,咱們這裏只須要關注cpu.開頭的文件。測試

cpu.cfs_period_us & cpu.cfs_quota_us

cfs_period_us用來配置時間週期長度,cfs_quota_us用來配置當前cgroup在設置的週期長度內所能使用的CPU時間數,兩個文件配合起來設置CPU的使用上限。兩個文件的單位都是微秒(us),cfs_period_us的取值範圍爲1毫秒(ms)到1秒(s),cfs_quota_us的取值大於1ms便可,若是cfs_quota_us的值爲-1(默認值),表示不受cpu時間的限制。下面是幾個例子:ui

1.限制只能使用1個CPU(每250ms能使用250ms的CPU時間)
    # echo 250000 > cpu.cfs_quota_us /* quota = 250ms */
    # echo 250000 > cpu.cfs_period_us /* period = 250ms */

2.限制使用2個CPU(內核)(每500ms能使用1000ms的CPU時間,即便用兩個內核)
    # echo 1000000 > cpu.cfs_quota_us /* quota = 1000ms */
    # echo 500000 > cpu.cfs_period_us /* period = 500ms */

3.限制使用1個CPU的20%(每50ms能使用10ms的CPU時間,即便用一個CPU核心的20%)
    # echo 10000 > cpu.cfs_quota_us /* quota = 10ms */
    # echo 50000 > cpu.cfs_period_us /* period = 50ms */

cpu.shares

shares用來設置CPU的相對值,而且是針對全部的CPU(內核),默認值是1024,假如系統中有兩個cgroup,分別是A和B,A的shares值是1024,B的shares值是512,那麼A將得到1024/(1204+512)=66%的CPU資源,而B將得到33%的CPU資源。shares有兩個特色:code

  • 若是A不忙,沒有使用到66%的CPU時間,那麼剩餘的CPU時間將會被系統分配給B,即B的CPU使用率能夠超過33%server

  • 若是添加了一個新的cgroup C,且它的shares值是1024,那麼A的限額變成了1024/(1204+512+1024)=40%,B的變成了20%

從上面兩個特色能夠看出:

  • 在閒的時候,shares基本上不起做用,只有在CPU忙的時候起做用,這是一個優勢。

  • 因爲shares是一個絕對值,須要和其它cgroup的值進行比較才能獲得本身的相對限額,而在一個部署不少容器的機器上,cgroup的數量是變化的,因此這個限額也是變化的,本身設置了一個高的值,但別人可能設置了一個更高的值,因此這個功能無法精確的控制CPU使用率。

cpu.stat

包含了下面三項統計結果

  • nr_periods: 表示過去了多少個cpu.cfs_period_us裏面配置的時間週期

  • nr_throttled: 在上面的這些週期中,有多少次是受到了限制(即cgroup中的進程在指定的時間週期中用光了它的配額)

  • throttled_time: cgroup中的進程被限制使用CPU持續了多長時間(納秒)

示例

這裏以cfs_period_us & cfs_quota_us爲例,演示一下如何控制CPU的使用率。

#繼續使用上面建立的子cgroup: test
#設置只能使用1個cpu的20%的時間
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ sudo sh -c "echo 50000 > cpu.cfs_period_us"
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ sudo sh -c "echo 10000 > cpu.cfs_quota_us"

#將當前bash加入到該cgroup
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ echo $$
5456
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ sudo sh -c "echo 5456 > cgroup.procs"

#在bash中啓動一個死循環來消耗cpu,正常狀況下應該使用100%的cpu(即消耗一個內核)
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ while :; do echo test > /dev/null; done

#--------------------------從新打開一個shell窗口----------------------
#經過top命令能夠看到5456的CPU使用率爲20%左右,說明被限制住了
#不過這時系統的%us+%sy在10%左右,那是由於我測試的機器上cpu是雙核的,
#因此係統總體的cpu使用率爲10%左右
dev@ubuntu:~$ top
Tasks: 139 total,   2 running, 137 sleeping,   0 stopped,   0 zombie
%Cpu(s):  5.6 us,  6.2 sy,  0.0 ni, 88.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   499984 total,    15472 free,    81488 used,   403024 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   383332 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 5456 dev       20   0   22640   5472   3524 R  20.3  1.1   0:04.62 bash

#這時能夠看到被限制的統計結果
dev@ubuntu:~$ cat /sys/fs/cgroup/cpu,cpuacct/test/cpu.stat
nr_periods 1436
nr_throttled 1304
throttled_time 51542291833

結束語

使用cgroup限制CPU的使用率比較糾結,用cfs_period_us & cfs_quota_us吧,限制死了,無法充分利用空閒的CPU,用shares吧,又無法配置百分比,極其難控制。總之,使用cgroup的cpu子系統需謹慎。

參考

相關文章
相關標籤/搜索