Control Groups (Cgroups)-详解
1. ?Control Groups簡介 (Cgroups)
??? Red Hat Enterprise Linux 6 提供了一個新的內核特性: CONTROL GROUPS(Cgroups),它為內核提供的一種可以限制、記錄、隔離進程組(process groups)所使用的物理資源(如:cpu,memory,IO等等)的機制。
??? CONTROL GROUPS包括如下子系統:
blkio -- 這個子系統為塊設備設定輸入/輸出限制,比如物理設備(磁盤,固態硬盤,USB 等等)。
cpu -- 這個子系統使用調度程序提供對 CPU 的 cgroup 任務訪問。
cpuacct -- 這個子系統自動生成 cgroup 中任務所使用的 CPU 報告。
cpuset -- 這個子系統為 cgroup 中的任務分配獨立 CPU(在多核系統)和內存節點。
devices -- 這個子系統可允許或者拒絕 cgroup 中的任務訪問設備。
freezer -- 這個子系統掛起或者恢復 cgroup 中的任務。
memory -- 這個子系統設定 cgroup 中任務使用的內存限制,并自動生成由那些任務使用的內存資源報告。
net_cls -- 這個子系統使用等級識別符(classid)標記網絡數據包,可允許 Linux 流量控制程序(tc)識別從具體 cgroup 中生成的數據包。
ns -- 名稱空間子系統。
2. 使用 Control Groups
2.1 安裝啟動
2.1.1 安裝
# yum install –y libcgroup
2.1.2 啟動/停止
?????? # service cgconfig start
?????? # service cgconfig stop
2.2 創建配置文件
2.2.1 配置文件 /etc/cgconfig.conf
/etc/cgconfig.conf在安裝Cgroup后會自動建立,文件包含2部分功能----mount and group:
# cat /etc/cgconfig.conf
mount {
??????? cpuset? = /cgroup/cpuset;
??????? cpu???? = /cgroup/cpu;
??????? cpuacct = /cgroup/cpuacct;
??????? memory? = /cgroup/memory;
??????? devices = /cgroup/devices;
?????? ?freezer = /cgroup/freezer;
??????? net_cls = /cgroup/net_cls;
??????? blkio?? = /cgroup/blkio;
}
它將在服務啟動后創建和掛載虛擬文件系統,等價于命令:
# mkdir -p /cgroup/cpuset
# mount -t cgroup -o cpuset cpuset /cgroup/cpuset
…….
?
Example:
group daemons {
???? cpuset {
???????? cpuset.mems = 0;
???????? cpuset.cpus = 0;
???? }
}
group daemons/sql {
???? perm {
???????? task {
???????????? uid = root;
???????????? gid = sqladmin;
???????? }
admin {
???????????? uid = root;
???????????? gid = root;
???????? }
???? }
???? cpuset {
? ???????cpuset.mems = 0;
???????? cpuset.cpus = 0;
???? }
}
相當于在shell里面執行:
# mkdir -p /cgroup/cpuset/daemons/sql
# chown root:root -R /cgroup/cpuset/daemons
# chown root:sqladmin /cgroup/cpuset/daemons/sql/tasks
# echo $(cgget -n -v -r cpuset.mems /) > /cgroup/cpuset/daemons/cpuset.mems
# echo $(cgget -n -v -r cpuset.cpus /) > /cgroup/cpuset/daemons/cpuset.cpus
# echo 0 > /cgroup/cpuset/daemons/sql/cpuset.mems
# echo 0 > /cgroup/cpuset/daemons/sql/cpuset.cpus
2.2.2 目錄 /etc/cgconfig.d/
配置文件所在的目錄。下面的文件名以conf作為后綴,語法參見/etc/cgconfig.conf。
cgconfig服務啟動時第一個讀取的文件是/etc/cgconfig.conf,然后是該目錄下的*.conf文件。文件的解析沒有排序。不要在多個文件內定義同一個group。
2.3 列出當前的子系統
#? lssubsys -am
ns
perf_event
net_prio
cpuset /cgroup/cpuset
cpu /cgroup/cpu
cpuacct /cgroup/cpuacct
memory /cgroup/memory
devices /cgroup/devices
freezer /cgroup/freezer
net_cls /cgroup/net_cls
blkio /cgroup/blkio
第一列為支持的子系統名稱,后面的表示已經掛載的目錄。
也可查看指定的子系統:
#? lssubsys -m subsystems
subsystems為指定的子系統名稱。
2.4 remount/umount
對于已經掛載的子系統,同樣可以再次掛載:
# mount -t cgroup -o remount,cpu cpu_and_mem /cgroup/cpu
# umount /cgroup/ cpu
2.5 管理Control Groups
2.5.1?創建 Control Groups
語法:cgcreate -t uid:gid -a uid:gid -g subsystems:path
-t 指定允許向 cgroup 分配任務的用戶和組 ID
-a 指定允許管理 cgroup 和更改子系統參數的用戶和組 ID
-g subsystems:path??? group名稱及掛載路徑
Example:
# cgcreate -g cpu,net_cls:/test-subgroup
創建了cpu及net_cls子系統并掛載到/test-subgroup。
2.5.2?刪除 Control Groups
語法:cgdelete subsystems:path
Example:
# cgcreate cpu,net_cls:/test-subgroup
2.5.3?設置 Control Groups參數
語法:cgset -r parameter=value path_to_cgroup
如果cpuset 已經掛載到 /cgroup/cpu_and_mem/ 并且存在目錄/cgroup/cpu_and_mem/group1,那么可以:
# cgset -r cpuset.cpus=0-1 group1
也可以:
# echo ‘0-1’ > /cgroup/cpu_and_mem/group1/cpuset.cpus
2.5.4?復制 Control Groups參數
也可以對一個已經存在并設置好的參數進行復制。
語法:cgset --copy-from path_to_source_cgroup path_to_target_cgroup
# cgset --copy-from group1/ group2/
這樣croup2的參數將從group1復制而來。
2.6?應用Control Groups
設置好參數后,就可以對進程應用Cgroup。
語法:cgclassify -g subsystems:path_to_cgroup pidlist
# cgclassify -g cpu,memory:group1 1701
ID為1701的進程進程將被應用到cpu及memory子系統中的group1中。也就是說ID為1701的進程將受到cpu及memory子系統中的group1中所設定參數的限制。
也可以:
# echo 1701 > /cgroup/cpu_and_mem/group1/tasks
2.7?cgred Service
Cgred 服務會啟動一個守護進程 cgrulesengd ,它可根據在 /etc/cgrules.conf 文件中設定的參數將任務移動到 cgroup 中。/etc/cgrules.conf 文件可以使用以下兩個格式之一:
User?????? hierarchies???????? control_group
例如:
maria???????? devices?????? staff
用戶maria 的進程根據在 staff cgroup 中指定的參數訪問設備子系統。
啟動/停止方法:service cgred start/stop
/etc/cgrules.conf 文件中的條目可包括以下特殊符號:
@ - 當在 user 使用前綴時,代表是一個組群而不是單獨用戶。例如:@admins 是 admins 組群中的所有用戶。
* - 代表“所有”。例如:subsystem 字段中的 * 代表所有子系統。
% - 代表與以上行中項目相同的項目。例如:
@adminstaff?????? devices?????? /admingroup
@labstaff???? ??? %????? ?????? %(等價于
@labstaff???? ??? devices?????? /admingroup)
2.8?將進程放進cgroup中
語法:cgexec -g subsystems:path_to_cgroup command arguments
subsystems 是用逗號分開的子系統列表或者用 * 表示所有可用的子系統。
path_to_cgroup 是該 cgroup 的路徑。
command 是要運行的命令。
arguments 是該命令所有參數。
還可以在 command 前面添加 -- sticky 將所有子進程放在同一 cgroup 中。如果沒有設定這個選項,且 cgred 守護進程正在運行,則將根據在/etc/cgrules.conf 中的設置將子進程分配到 cgroup 中。而該進程本身仍保留在啟動它的 cgroup 中。
Example:
# cgexec -g cpu:group1 firefox
這樣firefox的進程將被放到cpu子系統的group1中。
也可以:
# echo $$ > /cgroup/lab1/group1/tasks
這樣的話,不但firefox進程會被放到相應的cgroup中;在當前窗口的所有進程均會被放到該cgroup中。如果不希望這樣的后果,可以:
# sh -c "echo \$$ > /cgroup/cpu_and_mem/group1/tasks && firefox"
2.8.1?將服務放進cgroup中
要將一個服務放到cgroup中,服務需要具備以下條件:
ⅰ可以使用 /etc/sysconfig/servicename 文件。
ⅱ必須使用 /etc/init.d/functions 的 daemon() 功能啟動該服務
然后編輯文件/etc/sysconfig/servicename,添加內容:CGROUP_DAEMON="subsystem:control_group"
Example:
# cat /etc/sysconfig/httpd
CGROUP_DAEMON="cpuset:group1"
# service httpd start
httpd服務將被加到cpuset子系統的group1中。
2.9?工具
2.9.1?生成配置文件之cgsnapshot
列出當前配置
# cgsnapshot –s
輸出配置文件
# cgsnapshot -f ~/test/cgconfig_test.conf
不要將輸出文件直接輸出到 /etc/cgconfig.conf,因為 -f 參數將會覆蓋任何文件。
也可以為子系統創建配置文件。通過指定一個子系統的名稱,則輸出將包含于該子系統的相應配置的:
# cgsnapshot cpuacct
設置黑名單
# cgsnapshot -b ~/test/my_blacklist.conf
如果不指定文件,則使用默認文件/etc/cgsnapshot_blacklist.conf。
設置白名單
# cgsnapshot -w ~/test/my_whitelist.conf
沒有用默認文件。
另,在使用cgsnapshot –f時,如果既不指定黑名單,也不指定白名單,那么會有相關的警告信息。因此可以使用 -t 參數。
2.10?查找某個屬于cgroup的進程
# ps -O cgroup
如果已知進程的PID,則可以:
# cat /proc/PID/cgroup
2.11?查找Control Groups
列出系統中的cgroup
# lscgroup
也可以:
# lscgroup controller:path
Example:
# lscgroup cpuset:daemons
2.12?查找Control Groups參數
顯示具體 cgroup 的參數:
# cgget -r parameter list_of_cgroups
Example:
# cgget -r cpuset.cpus -r memory.limit_in_bytes group1 group2
顯示 cgroup?lab1?和?lab2?的?cpuset.cpus?和?memory.limit_in_bytes?值。
如果不知道 parameter ,可以:
# cgget -g cpuset /
2.13.?卸載控制組群
要清除整個 cgroup 文件系統,請使用 cgclear 命令。
如果有些group沒有寫在配置文件中那么使用該命令后想要再次恢復,那么只能手動操作。
3. 子系統和可調參數
3.1.?blkio
blkio限額類是主要有兩種策略,一種是基于完全公平隊列調度(CFQ:Completely Fair Queuing )的按權重分配各個 cgroup 所能占用總體資源的百分比,好處是當資源空閑時可以充分利用,但只能用于最底層節點 cgroup 的配置;另一種則是設定資源使用上限,這種限額在各個層次的 cgroup 都可以配置,但這種限制較為生硬,并且容器之間依然會出現資源的競爭。
blkio?子系統提供2種策略來控制訪問 I/O:
權重比例。
I/O 使用上限。
3.1.1.?權重比例
blkio.weight
設定默認使用的權重比例,取值范圍:100—1000。此值會被blkio.weight_device值覆蓋。
echo 500 > blkio.weight
blkio.weight_device
設定指定設備的使用的權重比例,取值范圍:100—1000。此值會覆蓋blkio.weight設定值。該值的格式為:major:minor?weight,即,主設備號:次設備號 權重。例如:設定硬盤sda的訪問權重為500.
# ll /dev/sda
brw-rw---- 1 root disk 8, 0 Aug 15 15:42 /dev/sda
主設備號為8,次設備號為0.
echo 8:0 500 > blkio.weight_device
3.1.2.?I/O?使用上限
blkio.throttle.read_bps_device / blkio.throttle.write_bps_device
指定 cgroup 中某設備每秒鐘讀/寫數據的字節上限。其格式為?major:minor bytes_per_second。
blkio.throttle.read_iops_device / blkio.throttle.write_iops_device
指定 cgroup 中某設備每秒鐘可以執行的讀/寫請求數上限。其格式為major:minor operations_per_second。
3.1.3.?blkio?統計參數
blkio.reset_stats
向該文件中寫入一個整數,可以重置該 cgroup 中的統計計數。
blkio.time
統計 cgroup 對具體設備的 I/O 訪問時間。內容有三個字段:major,?minor?和time。time?的單位為毫秒(ms); 格式major:minor milliseconds
blkio.sectors
統計 cgroup 對具體設備的扇區讀寫數。內容有三個字段:major,?minor?和sectors(表示磁盤的扇區數)。 格式 major:minor sector_count
blkio.avg_queue_size
統計平均IO隊列大小。這個報告只有在將系統設定為?CONFIG_DEBUG_BLK_CGROUP=y?時可用。
blkio.group_wait_time
cgroup 等待每個隊列的時間總計(單位為納秒 -- ns)。每次這個 cgroup 的隊列獲得一個時間單位時就會更新這個報告,因此如果在 cgroup 等待時間單位時讀取這個偽文件,則該報告將不會包含等待當前隊列中的操作的時間。請注意這個報告只有在將系統設定為?CONFIG_DEBUG_BLK_CGROUP=y?時可用。
blkio.empty_time
報告 cgroup 在沒有任何等待處理請求時花費的時間總計(單位為納秒 -- ns)。每次這個 cgroup 有等待處理請求時都會更新這個報告,因此如果在 cgroup 沒有任何等待處理請求是讀取這個偽文件,則該報告中不會包含消耗在當前空狀態中的時間。請注意這個報告只有在將該系統設定為?CONFIG_DEBUG_BLK_CGROUP=y?時可用。
blkio.idle_time
報告調度程序在 cgroup 等待比已經在其它隊列或者來自其它組群請求更好的請求時顯示閑置的時間總計(單位為納秒 -- ns)。每次該組群不顯示閑置時就會更新這個報告,因此如果您在 cgroup 閑置時讀取這個偽文件,則該報告將不會包括消耗在當前閑置狀態的時間。請注意,只有在將系統設定為?CONFIG_DEBUG_BLK_CGROUP=y時這個報告才可用。
blkio.dequeue
報告 cgroup 的 I/O 操作請求被具體設備從隊列中移除的次數。條目有三個字段:major、minor和number。major和minor是在Linux分配的設備中指定的設備類型和節點數,number是將該組群從隊列中移除的次數。請注意這個報告只有在將系統設定為CONFIG_DEBUG_BLK_CGROUP=y時可用。
blkio.io_serviced
統計 cgroup 對具體設備的讀寫操作數。內容有四個字段:major,?minor,operation?(read,?write,?sync, or?async)和?number(表示操作的次數)。 格式major:minor operation number
blkio.io_service_bytes
統計 cgroup對具體設備的讀寫字節數。內容有四個字段:major,?minor,?operation??(read,?write,?sync, or?async)和?bytes(表示傳輸的字節數)。 格式major:minor operation bytes
blkio.io_service_time
統計 cgroup 對指定設備的 I/O 操作發送請求和完成請求之間的時間。條目有四個字段:major,?minor,?operation?和?time,其中?time?的單位為納秒(ns)。
blkio.io_wait_time
統計 cgroup 對具體設備的 I/O 操作在隊列調度中等待的時間。內容有四個字段:major,minor,?operation?和?time,其中?time?的單位為納秒(ns),這意味著對于ssd硬盤也是有意義的。 格式major:minor operation time
blkio.io_merged
統計 cgroup 將 BIOS 請求合并到 I/O 操作請求的次數。內容有兩個字段:number和?operation。 格式number operation
blkio.io_queued
統計I/O 操作排隊的請求數。內容有兩個字段:number?和?operation(read,?write,?sync, or?async)。 ,格式number operation
blkio.throttle.io_serviced
統計 cgroup 對具體設備的讀寫操作數。blkio.io_serviced ?與blkio.throttle.io_serviced的不同之處在于,CFQ 調度請求隊列時,前者不會更新。
內容有四個字段:major,?minor,operation?(read,?write,?sync, or?async)和?number(表示操作的次數)。 格式major:minor operation operations_per_second
blkio.throttle.io_service_bytes
統計 cgroup對具體設備的讀寫字節數。blkio.io_service_bytes?與blkio.throttle.io_service_bytes?的不同之處在于,CFQ 調度請求隊列時,前者不會更新。內容有四個字段:major,?minor,?operation??(read,?write,?sync, or?async)和?bytes(表示傳輸的字節數)。 格式major:minor operation bytes_per_second.
blkio.recursive_*:各類型的統計都有一個遞歸版本,Docker 中使用的都是這個版本。獲取的數據與非遞歸版本是一樣的,但是包括 cgroup 所有層級的監控數據。
3.1.4.?Example Usage
1.? # lssubsys -am |grep blkio
blkio /cgroup/blkio
2.????? # mkdir /cgroup/blkio/test{1..3}
3.? # dd if=/dev/zero of=file_1 bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB) copied, 14.017 s, 74.8 MB/s
???????
# dd if=/dev/zero of=file_2 bs=1M count=1000
4?????? # sync && echo 3 > /proc/sys/vm/drop_caches
5.????? # cgexec -g blkio:test1 time dd if=file_1 of=/dev/null &
???????? # cgexec -g blkio:test2 time dd if=file_2 of=/dev/null &
6.????? # iotop –o
???????? Total DISK READ: 42.45 M/s ? | ???? Total DISK WRITE: 0.00 B/s
? ???? TID? PRIO? USER???? DISK READ? DISK WRITE? SWAPIN???? IO>??? COMMAND???????????????????????????????????????????????????????????? ???????????????????????????????????
45224 be/4 root?????? 25.71 M/s ???0.00 B/s? 0.00 % 99.99 % dd if=file_1 of=/dev/null
45222 be/4 root?????? 16.74 M/s??? 0.00 B/s? 0.00 % 12.12 % dd if=file_2 of=/dev/null
7.????? # echo 8:0???? 4096000 > /cgroup/blkio/test3/blkio.throttle.read_bps_device
8.????? # sync && echo 3 > /proc/sys/vm/drop_caches
9.????? # cgexec -g blkio:test3? dd if=file_1 of=/dev/null
10.?? # dd if=file_1 of=/dev/null
步驟1—6設定了test2為test1的讀取比例限定,即:test2 的讀取速度為test1讀取速度的一半。通過iotop的觀察,應用于test2的file_2的讀取速度接近應用于test1的file_1 的50% 。
步驟7—10中,比較了設定IO讀取上限與不設定上限的結果:步驟9的結果為3.1M/s,而步驟10的結果為42 M/s 。
blkio.throttle.* 的限制是針對整個 cgroup 組的,而不是針對組中單個進程的。
3.2.?cpu
CPU 資源的控制也有兩種策略,一種是完全公平調度 (CFS:Completely Fair Scheduler)策略,提供了限額和按比例分配兩種方式進行資源控制;另一種是實時調度(Real-Time Scheduler)策略,針對實時進程按周期分配固定的運行時間。配置時間都以微秒(μs)為單位,文件名中用us表示。
CPU 子系統提供2種調度方法:
Completely Fair Scheduler (CFS)?— 按指定比例分配調度CPU 的使用時間。可能會有搶占CPU的情況。
Real-Time scheduler (RT)?— 指定絕對時間分配CPU 。
3.2.1.?CFS Tunable Parameters
cpu.cfs_period_us
規定CPU的時間周期(單位是微秒)。最大值是1秒,最小值是1000微秒。如果在一個單CPU的系統內,要保證一個cgroup 內的任務在1秒的CPU周期內占用0.2秒的CPU時間,可以通過設置cpu.cfs_quota_us 為200000和cpu.cfs_period_us 為 1000000 。
cpu.cfs_quota_us
在單位時間內(即cpu.cfs_period_us設定值)可用的CPU最大時間(單位是微秒)。cpu.cfs_quota_us值可以大于cpu.cfs_quota_us值,例如在一個雙CPU的系統內,想要一個cgroup內的進程充分的利用2個CPU,可以設定cpu.cfs_quota_us為?200000?及cpu.cfs_period_us為?100000 。
當設定cpu.cfs_quota_us為-1時,表明不受限制,同時這也是默認值(除了root cgroup外)。
cpu.stat
CPU 時間的相關統計:
nr_periods?—周期間隔數。即,在指定了cfs_period_us后,經歷的數量。
nr_throttled?— 因超出cpu.cfs_quota_us的限額時間而被終止的次數。
throttled_time?—? cgroup里的task總共被限制了多少納秒。
Relative Shares Tunable Parameters
cpu.shares
通過一個整數的數值來調節cgroup所占用的cpu時間。例如,有2個cgroup(假設為CPU1,CPU2),其中一個(CPU1)cpu.shares設定為100另外一個(CPU2)設為200,那么CPU2所使用的cpu時間將是CPU1所使用時間的2倍。cpu.shares?的值必須為2或者高于2 。
注意,在一個四核的CPU系統上,如果cgroup?A設定使用CPU的比例為 25% ,cgroup?B?為75% 時, 并且1個進程在?cgroup?A中,3個進程在cgroup?B中,那么CPU的分配可能會像下面這樣:
| PID | cgroup | CPU | CPU share |
| 100 | A | 0 | 100% of CPU0 |
| 101 | B | 1 | 100% of CPU1 |
| 102 | B | 2 | 100% of CPU2 |
| 103 | B | 3 | 100% of CPU3 |
如果cgroup?A中的任務是閑置的,并沒有使用CPU,那么cgroup?B會借用剩余的CPU 。
如果一個cgroup設為1000,另外2個cgroup設為500,那么當第一組cgroup的進程滿負荷使用CPU時,它將被限定為全部可用CPU的50%;如果此時新加一組cgroup并設定為1000時,那么第一組cgroup將只能用到全部CPU的33%,余下的cgroup使用比例為:16.5%, 16.5%, 和 33%?。
3.2.2.?RT Tunable Parameters
cpu.rt_period_us
僅適用于實時調度機制, 該參數以微秒為單位指定了一個重新分配CPU的時間周期。如果一個cgroup內的任務想要在每秒周期內使用0.2秒的CPU絕對時間,需要設置cpu.rt_runtime_us為200000?及cpu.rt_period_us為1000000。
cpu.rt_runtime_us
僅適用于實時調度機制, 該參數以微秒為單位指定了一個cgroup內的任務在單位時間周期內最大可用的連續時間。如果一個cgroup內的任務想要在每秒周期內使用0.2秒的CPU絕對時間,需要設置cpu.rt_runtime_us為200000?及cpu.rt_period_us為1000000。
注意,這樣的設置僅限于在單顆CPU的系統上。如果是多CPU,比如雙CPU,可以設置cpu.cfs_quota_us為200000及cpu.cfs_period_us為100000。同時,不建議手動設置這2個參數,應當有系統來決定CPU的絕對時間。
3.2.3.?Example Usage
測試腳本
# cat /tmp/test.sh
=============================
while :; do i=$i++; done &
=============================
觀察腳本:很快CPU將被腳本跑滿。
# sh /tmp/test.sh
# top
1.? 限定腳本使用10%的CPU
# mkdir /cgroup/cpu/test
# echo 10000 > /cgroup/cpu/test/cpu.cfs_quota_us
//因為cpu.cfs_period_us默認值為 100000
# echo 46121 > /cgroup/cpu/test/tasks
# top
成功限定腳本的CPU使用率。
2.? 按比例使用CPU
# mkdir /cgroup/cpu/blue
# mkdir /cgroup/cpu/red
# sh /tmp/test.sh
# top
# echo 47533 > /cgroup/cpu/red/tasks
# sh /tmp/test.sh
# top
# echo 4096 > blue/cpu.shares
??? // cpu.shares的默認值為 1024
# echo 48104 > blue/tasks
# top
成功將CPU按使用比例1:4分給2個不同的cgrou 。
以上均假設為單顆CPU。
3.? 滿負荷跑滿多核CPU(以4核為例)
對于一個雙核的CPU,如果要滿負荷使用,REDHAT建議這樣設置
~]#?echo 200000 > /cgroup/cpu/red/cpu.cfs_quota_us
~]#?echo 100000 > /cgroup/cpu/red/cpu.cfs_period_us
然而在我的4核CPU上,通過簡單的測試,仍然只是跑滿單核CPU
# cat cpu.cfs_period_us
100000
# echo 400000 > cpu.cfs_quota_us
# cat tasks
6056
當啟動4個以上的測試腳本時,4核CPU被滿負荷利用。
# cat tasks
6056
6058
6060
6062
3.3.?cpuacct
這個子系統的配置是cpu子系統的補充,提供 CPU 資源用量的統計,時間單位都是納秒。
CPU資源使用報告
cpuacct.usage
cgroup中所有任務的CPU使用時長(納秒) 。
#?echo 0 > /cgroup/cpuacct/cpuacct.usage
將重置報告,重新進行統計。
cpuacct.stat
cgroup中所有任務的用戶和內核分別使用CPU的時長:
user?— 用戶所消耗的CPU 時間。
system?— 系統所消耗的CPU 時間。
變量USER_HZ定義了CPU的報告時間單位。
cpuacct.usage_percpu
cgroup中所有任務使用的每個cpu的時間(納秒)。
3.4.?cpuset
分配CPU及內存節點。
有一些參數是必須在移動任務到cgroup前設置的,例如,要移動一個任務到cpuset子系統,那么cpuset.cpus和cpuset.mems需要在這之前進行設置, 同時 Docker 中目前也只用到這兩個。
cpuset.cpus(必選) - cgroup可使用的CPU 。如0-2,16代表 0,1,2,16這4 個CPU 。
cpuset.mems(必選) - cgroup可使用的內存節點。如0-2,16代表 0,1,2,16 這4個可用節點。
cpuset.memory_migrate(可選) - 當cpuset.mems變化時內存頁上的數據是否 遷移(默認值0,不遷移;1,遷移)。
cpuset.cpu_exclusive(可選) - cgroup是否獨占cpuset.cpus 中分配的cpu 。 (默認值0,共享;1,獨占),如果設置為1,其他cgroup內的cpuset.cpus值不能包含有該cpuset.cpus內的值。
cpuset.mem_exclusive(可選) - 是否獨占memory,(默認值0,共享;1,獨 占)。
cpuset.mem_hardwall(可選) - cgroup中任務的內存是否隔離,(默認值0, 不隔離;1,隔離,每個用戶的任務將擁有獨立的空間)。
cpuset.memory_pressure(可選) - 只讀文件。統計了該cgroup的內存壓力平均值;在memory_pressure_enabled開啟時自動統計更新,否則內容為0 。
cpuset.memory_pressure_enabled(可選) - cpuset.memory_pressure開關, default 0
cpuset.memory_spread_page(可選) - 文件系統的buffer是否均勻的使用該 cgroup的內存節點。(默認值0,不均勻使用;1,均勻使用。)
cpuset.memory_spread_slab(可選) - 內核是否通過cpuset的設置為輸入/ 輸出系統進行均勻的cache 。(默認值0,不均勻使用;1,均勻使用。)
cpuset.sched_load_balance(可選) - cgroup的cpu壓力是否會被平均到 cpuset中的多個cpu上。(默認值1,啟用負載均衡;0,禁用。) 注意:如果父group啟用了該項,那么當前項被忽略。
cpuset.sched_relax_domain_level(可選) - cpuset.sched_load_balance的 策略 :
-1:使用系統默認值 ?
0:定期負載均衡? ?
1:實時在同一內核線程間進行負載均衡 ?
2:實時在同一內核包間負載均衡? ?
3:實時在同一cpu節點或者刀片上負載均衡 ?
4:實時在多個CPU(NUMA)節點負載均衡(“多個”猜測是指cpuset中設定的CPU)
5:實時在所有CPU(NUMA)節點負載均衡
3.5.?devices
限定cgroup內的進程是否可以訪問設備。
Red Hat Enterprise Linux 6 暫不支持。
devices.allow
允許訪問的設備。文件包括4個字段:type(設備類型), major(主設備號), minor(次設備號), and access(訪問方式)。 格式type major:minor access_type
type?????
?????? 可以有3個可選值:
?????? a — 適用所有設備,包括字符設備和塊設備
?????? b — 塊設備
?????? c — 字符設備
major,?minor
????可以使用具體的數字表示,也可以使用符號“*”表示所有,例如:
?????? 9:*
?????? *:*
?????? 8:1
access
?????? 可以有3個可選值:
?????? r — 讀
????? w — 寫
????? m — 創建不存在的設備
devices.deny
?????? 禁止訪問的設備,格式同devices.allow 。
devices.list
?????? 報告cgroup對設備的使用情況。
3.6.?freezer
只有一個屬性,表示進程的狀態,把 task 放到 freezer 所在的 cgroup,再把 state 改為 FROZEN,就可以暫停進程。不允許在 cgroup 處于 FROZEN 狀態時加入進程。
暫?;蚧謴腿蝿铡?/p>
freezer.state
僅出現在非root的cgroups中, 且只有3個可選值:
FROZEN?— 掛起進程。
FREEZING?— 進程正在掛起中。
THAWED?— 激活進程。
1.??? 掛起進程時,會連同子進程一同掛起。
2.??? 不能將進程移動到處于FROZEN狀態的cgroup中。
3.??? 只有FROZEN和THAWED可以被寫進freezer.state中,?FREEZING則不能。
3.6.1.?Example Usage
# cat freezer.state
THAWED
cgroup處于THAWED狀態時,19651的進程使用100%的cpu在運行。
# cat tasks
19651
# echo FROZEN > freezer.state
當把19651的進程寫進cgroup并使之處于FROZEN狀態時,該進程已從狀態“R”變為“D”。
# echo 26101 > tasks
-bash: echo: write error: Device or resource busy
試圖將其他進程寫進處于FROZEN狀態的cgroup時,報錯。
3.7.?memory
報告cgroup中的任務使用內存情況及限制對內存的使用。
默認的,在x86_64系統上,每一頁的物理內存會被內存子系統會消耗掉40個字節,即便是沒有任何的應用。如果要關閉掉內存子系統,可以編輯/boot/grub/grub.conf ,以root身份添加一行內容:cgroup_disable=memory 。
memory.stat
???????? 統計內存使用情況。各項單位為字節。其中:
active_anon + inactive_anon = anonymous memory + file cache for tmpfs + swap cache
active_anon + inactive_anon ≠ rss, because rss does not include tmpfs.
active_file + inactive_file = cache - size of tmpfs
- cache:頁緩存,包括 tmpfs(shmem),單位為字節。
- rss:匿名和 swap 緩存,不包括 tmpfs(shmem),單位為字節。
- mapped_file:memory-mapped 映射的文件大小,包括 tmpfs(shmem),單位為字節
- pgpgin:存入內存中的頁數
- pgpgout:從內存中讀出的頁數
- swap:swap 用量,單位為字節
- active_anon:在活躍的最近最少使用(least-recently-used,LRU)列表中的匿名和 swap 緩存,包括 tmpfs(shmem),單位為字節
- inactive_anon:不活躍的 LRU 列表中的匿名和 swap 緩存,包括 tmpfs(shmem),單位為字節
- active_file:活躍 LRU 列表中的 file-backed 內存,以字節為單位
- inactive_file:不活躍 LRU 列表中的 file-backed 內存,以字節為單位
- unevictable:無法再生的內存,以字節為單位
- hierarchical_memory_limit:包含 memory cgroup 的層級的內存限制,單位為字節
- hierarchical_memsw_limit:包含 memory cgroup 的層級的內存加 swap 限制,單位為字節
memory.usage_in_bytes
當前cgroup的內存使用情況(in bytes).
memory.memsw.usage_in_bytes
當前group的內存+swap的內存使用情況(in bytes).
memory.max_usage_in_bytes
報告進程使用的最大內存(in bytes).
memory.memsw.max_usage_in_bytes
報告進程使用的最大內存+swap(in bytes).
memory.limit_in_bytes
???設定最大的內存使用量,可以加單位(k/K,m/M,g/G)不加單位默認為bytes。
1:不能為root的group設定該參數。
2:子group的限制要小于父group?值。
3:-1取消限制。
memory.memsw.limit_in_bytes
??設定最大的內存+swap的使用量(參見memory.limit_in_bytes)。
memory.limit_in_bytes的設置對于此選項非常重要。該值的設定應該不小于memory.limit_in_bytes的設定值。
memory.failcnt
統計達到內存限制(memory.limit_in_bytes)的次數。
memory.memsw.failcnt
統計達到內存+swap限制(memory.memsw.limit_in_bytes) 的次數。
memory.soft_limit_in_bytes
???和 memory.limit_in_bytes 的差異是,這個限制并不會阻止進程使用超過限額的內存,只是在系統內存不足時,會優先回收超過限額的進程占用的內存,使之向限定值靠攏。該值應小于memory.limit_in_bytes設定值。
memory.force_empty
當設置為0時,清空該group的所有內存頁;該選項只有在當前group
沒有tasks才可以使用。
memory.swappiness
???該group的交換分區的優先級,值低于60時優先使用物理內存,大于60時,優先使用swap。
1:?不能調整root的group的swappiness??????????????
2:?不能調整有子group的swappiness
memory.move_charge_at_immigrate
??是否允許進程在group間進行遷移,1表示允許;0表示禁止。
memory.use_hierarchy
各個層次間的內存使用是否獨立。默認值0,表示獨立使用;當為1時,子層次中進程的內存使用會受到父層次設定值的影響。該項只能對于沒有子層次的group進行設定,并且會繼承父層次的設定。
memory.oom_control
當進程出現Out of Memory時,是否進行kill操作。默認值0,kill;設置為1時,進程將進入睡眠狀態,等待內存充足時被喚醒。
3.7.1.?Example Usage
# mkdir /cgroup/memory/blue
# cd /cgroup/memory/blue
# echo 100m > memory.limit_in_bytes
# echo $$ > tasks
# yes | awk '{mem[NR]=NR}'
當awk所使用的內存超過100M時將被kill掉。
# echo 1 > memory.oom_control
# yes | awk '{mem[NR]=NR}'
通過ps觀察,當awk超過100M內存時,將進入D狀態。
3.8.?net_cls
指定tc的handle,通過tc實現網絡控制。
3.9.?net_prio
??? 設置每個網絡接口 ( network interface ) 的優先級。該子系統并沒有像其他子系統一樣編譯進內核,而是需要另外加載才能使用:
# modprobe netprio_cgroup
net_prio.prioidx
???一個包含唯一整數的只讀文件。內核用這個數字來表示該group。
net_prio.ifpriomap
指定各個網卡的該group的優先級格式,
?????? 1:子group默認使用父group的優先級
2:值越大優先級越低
例如:
??? # cat /cgroup/net_prio/iscsi/net_prio.ifpriomap
eth0 5
eth1 4
3.10.?Common Tunable Parameters
一下參數會出現在已經存在的group中,而不管該group是否在使用中。
tasks
一個包含進程pid的列表,pid可能不是唯一的且沒有排序。把一個進程pid寫到這個文件中就表示把這個進程加入這個cgroup中。
cgroup.procs
??在該cgroup的線程組ID列表。這份名單不保證是排序的或沒有重復的TGID,如果需要,用戶空間程序應該對它進行排序或去重。
?? 寫一個線程組ID到這個文件將這個組所有的線程加到這個cgroup中。
notify_on_release
??是否在退出時運行release agent 。1 表示允許;0 表示禁止。
??Root級別的cgroup默認值是0,其他子group會繼承父group的設定值。
release_agent (present in the root cgroup only)
??包含一個可執行的命令。一旦一個cgroup清空了所有的進程并且notify_on_release處于打開狀態,內核將會執行該命令。
Example:
1.????? 建立一個可執行文件。
# cat /usr/local/bin/remove-empty-cpu-cgroup.sh
#!/bin/sh
rmdir /cgroup/cpu/$1
# chmod +x /usr/local/bin/remove-empty-cpu-cgroup.sh
2.????? 在cpu的cgroup中打開notify_on_release
# echo 1 > /cgroup/cpu/notify_on_release
3.????? 指定release_agent的執行命令
# echo "/usr/local/bin/remove-empty-cpu-cgroup.sh" > /cgroup/cpu/release_agent
4.????? 測試
# mkdir /cgroup/cpu/blue
# cat blue/notify_on_release
1
# cgexec -g cpu:blue dd if=/dev/zero of=/dev/null bs=1024k &
[1] 8623
# cat blue/tasks
8623
# kill -9 8623
# ls /cgroup/cpu/blue
ls: cannot access /cgroup/cpu/blue: No such file or directory
參考文獻:
Control Groups簡介 (Cgroups)-jiaogeshahaone-ChinaUnix博客
cgroup之子系統和可調參數-jiaogeshahaone-ChinaUnix博客
總結
以上是生活随笔為你收集整理的Control Groups (Cgroups)-详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓Activity的生命周期函数详解
- 下一篇: 新浪微博PC客户端(DotNet Win