1. 程式人生 > >Linux下CGroup進行CPU記憶體等資源控制

Linux下CGroup進行CPU記憶體等資源控制

留存

from: http://www.cnblogs.com/kevingrace/p/5685433.html  and  http://www.cnblogs.com/wang_yb/p/3942208.html

CGroup 介紹
CGroup 是 Control Groups 的縮寫,是 Linux 核心提供的一種可以限制、記錄、隔離程序組 (process groups) 所使用的物力資源 (如 cpu memory i/o 等等) 的機制。2007 年進入 Linux 2.6.24 核心,CGroups 不是全新創造的,它將程序管理從 cpuset 中剝離出來,作者是 Google 的 Paul Menage。CGroups 也是 LXC 為實現虛擬化所使用的資源管理手段。

CGroup 功能及組成
CGroup 是將任意程序進行分組化管理的 Linux 核心功能。CGroup 本身是提供將程序進行分組化管理的功能和介面的基礎結構,I/O 或記憶體的分配控制等具體的資源管理功能是通過這個功能來實現的。這些具體的資源管理功能稱為 CGroup 子系統或控制器。CGroup 子系統有控制記憶體的 Memory 控制器、控制程序排程的 CPU 控制器等。執行中的核心可以使用的 Cgroup 子系統由/proc/cgroup 來確認。
CGroup 提供了一個 CGroup 虛擬檔案系統,作為進行分組管理和各子系統設定的使用者介面。要使用 CGroup,必須掛載 CGroup 檔案系統。這時通過掛載選項指定使用哪個子系統。

Cgroups提供了以下功能:
1)限制程序組可以使用的資源數量(Resource limiting )。比如:memory子系統可以為程序組設定一個memory使用上限,一旦程序組使用的記憶體達到限額再申請記憶體,就會出發OOM(out of memory)。
2)程序組的優先順序控制(Prioritization )。比如:可以使用cpu子系統為某個程序組分配特定cpu share。
3)記錄程序組使用的資源數量(Accounting )。比如:可以使用cpuacct子系統記錄某個程序組使用的cpu時間
4)程序組隔離(Isolation)。比如:使用ns子系統可以使不同的程序組使用不同的namespace,以達到隔離的目的,不同的程序組有各自的程序、網路、檔案系統掛載空間。
5)程序組控制(Control)。比如:使用freezer子系統可以將程序組掛起和恢復。

CGroup 支援的檔案種類
表 1. CGroup 支援的檔案種類

檔名 R/W 用途

Release_agent

RW

刪除分組時執行的命令,這個檔案只存在於根分組

Notify_on_release

RW

設定是否執行 release_agent。為 1 時執行

Tasks

RW

屬於分組的執行緒 TID 列表

Cgroup.procs

R

屬於分組的程序 PID 列表。僅包括多執行緒程序的執行緒 leader 的 TID,這點與 tasks 不同

Cgroup.event_control

RW

監視狀態變化和分組刪除事件的配置檔案

CGroup 相關概念解釋
1)任務(task)。在 cgroups 中,任務就是系統的一個程序;
2)控制族群(control group)。控制族群就是一組按照某種標準劃分的程序。Cgroups 中的資源控制都是以控制族群為單位實現。一個程序可以加入到某個控制族群,也從一個程序組遷移到另一個控制族群。一個程序組的程序可以使用 cgroups 以控制族群為單位分配的資源,同時受到 cgroups 以控制族群為單位設定的限制;
3)層級(hierarchy)。控制族群可以組織成 hierarchical 的形式,既一顆控制族群樹。控制族群樹上的子節點控制族群是父節點控制族群的孩子,繼承父控制族群的特定的屬性;
4)子系統(subsystem)。一個子系統就是一個資源控制器,比如 cpu 子系統就是控制 cpu 時間分配的一個控制器。子系統必須附加(attach)到一個層級上才能起作用,一個子系統附加到某個層級以後,這個層級上的所有控制族群都受到這個子系統的控制。

相互關係
1)每次在系統中建立新層級時,該系統中的所有任務都是那個層級的預設 cgroup(我們稱之為 root cgroup,此 cgroup 在建立層級時自動建立,後面在該層級中建立的 cgroup 都是此 cgroup 的後代)的初始成員;
2)一個子系統最多隻能附加到一個層級;
3)一個層級可以附加多個子系統;
4)一個任務可以是多個 cgroup 的成員,但是這些 cgroup 必須在不同的層級;
5)系統中的程序(任務)建立子程序(任務)時,該子任務自動成為其父程序所在 cgroup 的成員。然後可根據需要將該子任務移動到不同的 cgroup 中,但開始時它總是繼承其父任務的 cgroup。

圖 1. CGroup 層級圖

圖 1. CGroup 層級圖

圖 1 所示的 CGroup 層級關係顯示,CPU 和 Memory 兩個子系統有自己獨立的層級系統,而又通過 Task Group 取得關聯關係。

CGroup 特點
在 cgroups 中,任務就是系統的一個程序。
控制族群(control group)。控制族群就是一組按照某種標準劃分的程序。Cgroups 中的資源控制都是以控制族群為單位實現。一個程序可以加入到某個控制族群,也從一個程序組遷移到另一個控制族群。一個程序組的程序可以使用 cgroups 以控制族群為單位分配的資源,同時受到 cgroups 以控制族群為單位設定的限制。
層級(hierarchy)。控制族群可以組織成 hierarchical 的形式,既一顆控制族群樹。控制族群樹上的子節點控制族群是父節點控制族群的孩子,繼承父控制族群的特定的屬性。
子系統(subsytem)。一個子系統就是一個資源控制器,比如 cpu 子系統就是控制 cpu 時間分配的一個控制器。子系統必須附加(attach)到一個層級上才能起作用,一個子系統附加到某個層級以後,這個層級上的所有控制族群都受到這個子系統的控制。

子系統的介紹
blkio -- 這個子系統為塊裝置設定輸入/輸出限制,比如物理裝置(磁碟,固態硬碟,USB 等等)。
cpu -- 這個子系統使用排程程式提供對 CPU 的 cgroup 任務訪問。
cpuacct -- 這個子系統自動生成 cgroup 中任務所使用的 CPU 報告。
cpuset -- 這個子系統為 cgroup 中的任務分配獨立 CPU(在多核系統)和記憶體節點。
devices -- 這個子系統可允許或者拒絕 cgroup 中的任務訪問裝置。
freezer -- 這個子系統掛起或者恢復 cgroup 中的任務。
memory -- 這個子系統設定 cgroup 中任務使用的記憶體限制,並自動生成由那些任務使用的記憶體資源報告。
net_cls -- 這個子系統使用等級識別符(classid)標記網路資料包,可允許 Linux 流量控制程式(tc)識別從具體 cgroup 中生成的資料包。

圖 2. CGroup 典型應用架構圖

圖 2. CGroup 典型應用架構圖

如圖 2 所示,CGroup 技術可以被用來在作業系統底層限制物理資源,起到 Container 的作用。圖中每一個 JVM 程序對應一個 Container Cgroup 層級,通過 CGroup 提供的各類子系統,可以對每一個 JVM 程序對應的執行緒級別進行物理限制,這些限制包括 CPU、記憶體等等許多種類的資源。下一部分會具體對應用程式進行 CPU 資源隔離進行演示。

cgroup的安裝
其實安裝很簡單,最佳實踐就是yum直接安裝(centos下)

配置檔案

1 2 3 4 5 6 7 8 9 10 [[email protected] ~]# vim /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;              }

cgroup section的語法格式如下:
group <name> {
     [<permissions>]
     <controller> {
        <param name> = <param value>;
        …
     }
      …}

其中:
name: 指定cgroup的名稱
permissions:可選項,指定cgroup對應的掛載點檔案系統的許可權,root使用者擁有所有許可權。
controller:子系統的名稱
param name 和 param value:子系統的屬性及其屬性值

1.配置對mysql例項的資源限制

1.1 修改cgconfig.conf檔案

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 mount cpuset  =/cgroup/cpuset cpu =/cgroup/cpu cpuacct =/cgroup/cpuacct memory  =/cgroup/memory blkio   =/cgroup/blkio group mysql_g1 {    cpu {  cpu.cfs_quota_us = 50000;  cpu.cfs_period_us = 100000;  cpuset {    cpuset.cpus ="3";    cpuset.mems ="0";    }    cpuacct{  memory {    memory.limit_in_bytes=104857600;  memory.swappiness=0;  # memory.max_usage_in_bytes=104857600;  # memory.oom_control=0;  }   blkio  {  blkio.throttle.read_bps_device="8:0 524288" blkio.throttle.write_bps_device="8:0 524288" }   }

1.2 配置檔案的部分解釋
cpu:cpu使用時間限額

cpu.cfs_period_us和cpu.cfs_quota_us來限制該組中的所有程序在單位時間裡可以使用的cpu時間。這裡的cfs是完全公平排程器的縮寫。cpu.cfs_period_us就是時間週期(微秒),預設為100000,即百毫秒。cpu.cfs_quota_us就是在這期間內可使用的cpu時間(微秒),預設-1,即無限制。(cfs_quota_us是cfs_period_us的兩倍即可限定在雙核上完全使用)。
cpuset:cpu繫結
我們限制該組只能在0一共1個超執行緒上執行。cpuset.mems是用來設定記憶體節點的。
本例限制使用超執行緒0上的第四個cpu執行緒。
其實cgconfig也就是幫你把配置檔案中的配置整理到/cgroup/cpuset這個目錄裡面,比如你需要動態設定mysql_group1/ cpuset.cpus的CPU超執行緒號,可以採用如下的辦法。
[[email protected] ~]# echo "0" > mysql_group1/ cpuset.cpus
cpuacct:cpu資源報告
memory:記憶體限制

記憶體限制我們主要限制了MySQL可以使用的記憶體最大大小memory.limit_in_bytes=256M。而設定swappiness為0是為了讓作業系統不會將MySQL的記憶體匿名頁交換出去。
blkio:BLOCK IO限額
blkio.throttle.read_bps_device="8:0 524288"; #每秒讀資料上限
blkio.throttle.write_bps_device="8:0 524288"; #每秒寫資料上限
其中8:0對應主裝置號和副裝置號,可以通過ls -l /dev/sda檢視
[[email protected] ~]# ls -l /dev/sda
brw-rw----. 1 root disk 8, 0 Sep 15 04:19 /dev/sda

1.3 拓展知識
現在較新的伺服器CPU都是numa結構<非一致記憶體訪問結構(NUMA:Non-Uniform Memory Access)>,使用numactl --hardware可以看到numa各個節點的CPU超執行緒號,以及對應的節點號。

本例結果如下:
[[email protected] ~]# numactl --hardware
available: 1 nodes (0)
node 0 cpus: 0 1 2 3
node 0 size: 1023 MB
node 0 free: 68 MB
node distances:
node 0
0: 10
以下是較高階伺服器的numa資訊,僅作參考
[[email protected] ~]# numactl --hardware
available: 4 nodes (0-3)
node 0 cpus: 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60
node 0 size: 16338 MB
node 0 free: 391 MB
node 1 cpus: 1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61
node 1 size: 16384 MB
node 1 free: 133 MB
node 2 cpus: 2 6 10 14 18 22 26 30 34 38 42 46 50 54 58 62
node 2 size: 16384 MB
node 2 free: 137 MB
node 3 cpus: 3 7 11 15 19 23 27 31 35 39 43 47 51 55 59 63
node 3 size: 16384 MB
node 3 free: 186 MB
node distances:
node 0 1 2 3
0: 10 20 30 20
1: 20 10 20 30
2: 30 20 10 20
3: 20 30 20 10

1.4 修改cgrules.conf檔案
[[email protected] ~]# vim /etc/cgrules.conf
# /etc/cgrules.conf
#The format of this file is described in cgrules.conf(5)
#manual page.
#
# Example:
#<user> <controllers> <destination>
#@student cpu,memory usergroup/student/
#peter cpu test1/
#% memory test2/
*:/usr/local/mysql/bin/mysqld * mysql_g1
注:共分為3個部分,分別為需要限制的例項,限制的內容(如cpu,memory),掛載目標。

2 使配置生效

[[email protected] ~]# /etc/init.d/cgconfig restart
Stopping cgconfig service: [ OK ]
Starting cgconfig service: [ OK ]
[[email protected] ~]# /etc/init.d/cgred restart
Stopping CGroup Rules Engine Daemon... [ OK ]
Starting CGroup Rules Engine Daemon: [ OK ]
注:重啟順序為cgconfig -> cgred ,更改配置檔案後兩個服務需要重啟,且順序不能錯。

3 啟動MySQL,檢視MySQL是否處於cgroup的限制中

[[email protected] ~]# ps -eo pid,cgroup,cmd | grep -i mysqld
29871 blkio:/;net_cls:/;freezer:/;devices:/;memory:/;cpuacct:/;cpu:/;cpuset:/ /bin/sh ./bin/mysqld_safe --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/
30219 blkio:/;net_cls:/;freezer:/;devices:/;memory:/;cpuacct:/;cpu:/;cpuset:/mysql_g1 /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/ --plugin-dir=/usr/local/mysql//lib/plugin --user=mysql --log-error=/usr/local/mysql/data//localhost.localdomain.err --pid-file=/usr/local/mysql/data//localhost.localdomain.pid --socket=/tmp/mysql.sock --port=3306
30311 blkio:/;net_cls:/;freezer:/;devices:/;memory:/;cpuacct:/;cpu:/;cpuset:/ grep -i mysqld

4 資源限制驗證

使用mysqlslap對mysql進行壓力測試,看mysql使用資源是否超過限制

4.1 在shell視窗1用mysqlslap對mysql進行壓力測試
[[email protected] ~]# /usr/local/mysql/bin/mysqlslap --defaults-file=/etc/my.cnf --concurrency=150 --iterations=1 --number-int-cols=8 --auto-generate-sql --auto-generate-sql-load-type=mixed --engine=innodb --number-of-queries=100000 -ujesse -pjesse --number-char-cols=35 --auto-generate-sql-add-autoincrement --debug-info -P3306 -h127.0.0.1

4.2 在shell視窗2檢視mysql對cpu,記憶體的使用

可見:cpu限制在了第四個核心上,且對第四個核心的使用限制在50%。

4.3 在shell視窗3檢視io的消耗

可見:mysql對io的讀及寫消耗均限制在2M每秒以內。

cgroup例項分析(手工動態驗證)

還原配置檔案/etc/cgconfig.conf及/etc/cgrules.conf 為預設配置。測試例項依然為mysql,測試工具為mysqlslap。

開啟cgconfig及cgrules 服務
[[email protected] ~]# /etc/init.d/cgconfig restart
Stopping cgconfig service: [ OK ]
Starting cgconfig service: [ OK ]
[[email protected] /]# /etc/init.d/cgred restart
Stopping CGroup Rules Engine Daemon... [ OK ]
Starting CGroup Rules Engine Daemon: [ OK ]

開啟mysqlslap壓力測試程式
[[email protected] /]# /usr/local/mysql/bin/mysqlslap --defaults-file=/etc/my.cnf --concurrency=150 --iterations=1 --number-int-cols=8 --auto-generate-sql --auto-generate-sql-load-type=mixed --engine=innodb --number-of-queries=100000 -ujesse -pjesse --number-char-cols=35 --auto-generate-sql-add-autoincrement --debug-info -P3306 -h127.0.0.1

通過htop檢視資源消耗。

1)cpu限制例項

限制mysql使用一個核,如第2個核,且對該核的使用不超過50%
[[email protected] ~]# mkdir -p /cgroup/cpu/foo/
[[email protected] ~]# mkdir -p /cgroup/cpuset/foo/
[[email protected] ~]# echo 50000 > /cgroup/cpu/foo/cpu.cfs_quota_us
[[email protected] ~]# echo 100000 > /cgroup/cpu/foo/cpu.cfs_period_us
[[email protected] ~]# echo "0" > /cgroup/cpuset/foo/cpuset.mems
[[email protected] ~]# echo "1" > /cgroup/cpuset/foo/cpuset.cpus
[[email protected] ~]# echo 28819 > /cgroup/cpu/foo/tasks

其中:28819為mysqld的程序號。

2) 記憶體限制例項

限制mysql使用記憶體為不超過512M
跑一個消耗記憶體指令碼

1 2 3 4 #!/bin/bash<br>x='a'  while [ True ];do  x=$x$x  done;

記憶體的消耗在不斷增加,對其進行限制,使其使用記憶體在500M以內
[[email protected] ~]# mkdir -p /cgroup/memory/foo
[[email protected] ~]# echo 524288000 > /cgroup/memory/foo/memory.limit_in_bytes
[[email protected] ~]# echo 44476 > /cgroup/memory/foo/tasks


記憶體使用得到了有效控制。

3)IO限制例項

跑一個消耗IO的測試
[[email protected] ~]# dd if=/dev/sda of=/dev/null
通過iotop看io佔用情況,磁碟讀取速度到了50M/s

 
限制讀取速度為10M/S

[[email protected] ~]# mkdir -p /cgroup/blkio/foo
[[email protected] ~]# echo '8:0 10485760' > /cgroup/blkio/foo/blkio.throttle.read_bps_device
[[email protected] ~]# echo 45033 > /cgroup/blkio/foo/tasks
注1:45033為dd的程序號
注2:8:0對應主裝置號和副裝置號,可以通過ls -l /dev/sda檢視
[[email protected] ~]# ls -l /dev/sda
brw-rw----. 1 root disk 8, 0 Sep 15 04:19 /dev/sda

cgroup小結

使用cgroup臨時對程序進行調整,直接通過命令即可,如果要持久化對程序進行控制,即重啟後依然有效,需要寫進配置檔案/etc/cgconfig.conf及/etc/cgrules.conf 

***************當你發現自己的才華撐不起野心時,就請安靜下來學習吧***************

==================================================================

¥¥='$$'

 Linux資源控制-CPU和記憶體
http://www.cnblogs.com/wang_yb/p/3942208.html
主要介紹Linux下, 如果對程序的CPU和記憶體資源的使用情況進行控制的方法。
 
CPU資源控制
每個程序能夠佔用CPU多長時間, 什麼時候能夠佔用CPU是和系統的排程密切相關的.
Linux系統中有多種排程策略, 各種排程策略有其適用的場景, 也很難說哪種排程策略是最優的.
Linux的排程策略可以參見程式碼: include/linux/sched.h
/*
 * Scheduling policies
 */
#define SCHED_NORMAL        0
#define SCHED_FIFO        1
#define SCHED_RR        2
#define SCHED_BATCH        3
/* SCHED_ISO: reserved but not implemented yet */
#define SCHED_IDLE        5
/* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */
#define SCHED_RESET_ON_FORK     0x40000000
 
Linux 系統也提供了修改排程策略的命令和系統呼叫介面.
呼叫介面請查詢相關文件, 這裡主要介紹一下修改排程策略的命令 - chrt.
# 在一個終端中執行
sleep 1000
# 開啟另一個終端
ps -ef | grep sleep  # 找出 sleep 1000 的pid, 這裡假設是 1234
chrt -p 1234         # 可以檢視 pid=1234 的程序的 排程策略, 輸入如下:
      pid 1234's current scheduling policy: SCHED_OTHER
      pid 1234's current scheduling priority: 0
chrt -p -f 10 1234   # 修改排程策略為 SCHED_FIFO, 並且優先順序為10
chrt -p 1234         # 再次檢視排程策略
      pid 1234's current scheduling policy: SCHED_FIFO
      pid 1234's current scheduling priority: 10
 
補充:
    chrt 也可以直接指定一條命令, 並設定這條命令的優先順序的排程策略, 具體檢視 chrt --help
    檢視一個程序的排程策略, 除了使用 chrt 命令之外, 還可以 cat /proc/<PID>/sched
 
實時程序的CPU控制
所謂的實時程序, 也就是那些對響應時間要求比較高的程序.
這類程序需要在限定的時間內處理使用者的請求, 因此, 在限定的這段時間內, 需要佔用所有CPU資源, 並且不能被其它程序打斷.
在這種情況下, 如果實時程序中出現了類似死迴圈之類的情況, 就會導致整個系統無響應.
因為實時程序的CPU優先順序高, 並且未處理完之前是不會釋放CPU資源的.
 
所以, 核心中需要有一種方式來限制實時程序的CPU資源佔用.
 
系統整體設定
1. 獲取當前系統的設定
sysctl -n kernel.sched_rt_period_us   # 實時程序排程的單位CPU時間 1 秒
1000000
sysctl -n kernel.sched_rt_runtime_us  # 實時程序在 1 秒中實際佔用的CPU時間, 0.95秒
950000
這個設定說明實時程序在執行時並不是完全佔用CPU的, 每1秒中有0.05秒的時間可以給其它程序執行.
這樣既不會對實時程序的響應時間造成太大的影響, 也避免了實時程序卡住時導致整個系統無響應.
 
2. 設定實時程序佔用CPU時間
上面的預設設定中, 實時程序佔用 95% 的CPU時間. 如果覺得佔用的太多或太少, 都是可以調整的.比如:
sysctl -w kernel.sched_rt_runtime_us=900000    # 設定實時程序每1秒中只佔0.9秒的CPU時間
kernel.sched_rt_runtime_us = 900000
sysctl -n kernel.sched_rt_runtime_us
900000
 
cgroup 中的設定
整體設定是針對整個系統的, 我們也可以通過 cgroup 來對一組程序的CPU資源進行控制.
如果想在 cgroup 中對 sched_rt_period_us 和 sched_rt_runtime_us 進行控制, 需要核心編譯選項 CONFIG_RT_GROUP_SCHED=y
檢視當前系統的核心編譯選項方法如下: (debian 7.6 系統)
cat /boot/config-`uname -r`
檢視 CONFIG_RT_GROUP_SCHED 是否啟用
cat /boot/config-`uname -r` | grep -i rt_group
# CONFIG_RT_GROUP_SCHED is not set
debian 7.6 預設沒有啟動這個選項, 所以掛載cgroup之後, 沒有設定 sched_rt_period_us 和 sched_rt_runtime_us 的檔案
mkdir /mnt/cgroup
mount -t cgroup cgroup /mnt/cgroup/
cd /mnt/cgroup/
ls -l
total 0
-r--r--r-- 1 root root 0 Aug 28 09:06 blkio.io_merged
-r--r--r-- 1 root root 0 Aug 28 09:06 blkio.io_queued
-r--r--r-- 1 root root 0 Aug 28 09:06 blkio.io_service_bytes
-r--r--r-- 1 root root 0 Aug 28 09:06 blkio.io_serviced
-r--r--r-- 1 root root 0 Aug 28 09:06 blkio.io_service_time
-r--r--r-- 1 root root 0 Aug 28 09:06 blkio.io_wait_time
--w------- 1 root root 0 Aug 28 09:06 blkio.reset_stats
-r--r--r-- 1 root root 0 Aug 28 09:06 blkio.sectors
-r--r--r-- 1 root root 0 Aug 28 09:06 blkio.time
-rw-r--r-- 1 root root 0 Aug 28 09:06 blkio.weight
-rw-r--r-- 1 root root 0 Aug 28 09:06 blkio.weight_device
-rw-r--r-- 1 root root 0 Aug 28 09:06 cgroup.clone_children
--w--w--w- 1 root root 0 Aug 28 09:06 cgroup.event_control
-rw-r--r-- 1 root root 0 Aug 28 09:06 cgroup.procs
-r--r--r-- 1 root root 0 Aug 28 09:06 cpuacct.stat
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuacct.usage
-r--r--r-- 1 root root 0 Aug 28 09:06 cpuacct.usage_percpu
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.cpu_exclusive
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.cpus
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.mem_exclusive
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.mem_hardwall
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.memory_migrate
-r--r--r-- 1 root root 0 Aug 28 09:06 cpuset.memory_pressure
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.memory_pressure_enabled
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.memory_spread_page
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.memory_spread_slab
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.mems
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.sched_load_balance
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpuset.sched_relax_domain_level
-rw-r--r-- 1 root root 0 Aug 28 09:06 cpu.shares
--w------- 1 root root 0 Aug 28 09:06 devices.allow
--w------- 1 root root 0 Aug 28 09:06 devices.deny
-r--r--r-- 1 root root 0 Aug 28 09:06 devices.list
-rw-r--r-- 1 root root 0 Aug 28 09:06 net_cls.classid
-rw-r--r-- 1 root root 0 Aug 28 09:06 notify_on_release
-rw-r--r-- 1 root root 0 Aug 28 09:06 release_agent
-rw-r--r-- 1 root root 0 Aug 28 09:06 tasks
 
果然, 只有cpu.share, 沒有 cpu.sched_rt_period_us 和 cpu.sched_rt_runtime_us
沒辦法, 重新編譯核心, 編譯核心的具體方法參見:  編譯Linux核心
為了節約時間, 我們用 make localmodconfig 來建立 .config 檔案, 然後修改其中的 CONFIG_RT_GROUP_SCHED=y
下載原始碼等等參見: 編譯Linux核心, 主要步驟如下:
cd /path/to/linux-source-3.2
make localmodconfig
vim .config   # 設定 CONFIG_RT_GROUP_SCHED=y 並儲存
make
make modules_install
make install
reboot      # 重啟之前看看 /boot/grub/grub.cfg 中, 預設啟動的是不是新安裝的核心
 
啟動到新核心, 再次檢視核心選項 CONFIG_RT_GROUP_SCHED 是否啟用
cat /boot/config-`uname -r` | grep -i rt_group
CONFIG_RT_GROUP_SCHED=y       # 已啟用
 
再次掛載 cgroup 檔案系統, 發現多了2個配置檔案, cpu.rt_period_us 和 cpu.rt_runtime_us
mount -t cgroup cgroup /mnt/cgroup/
cd /mnt/cgroup/
ls -l
total 0
-r--r--r-- 1 root root 0 Aug 28 09:53 blkio.io_merged
-r--r--r-- 1 root root 0 Aug 28 09:53 blkio.io_queued
-r--r--r-- 1 root root 0 Aug 28 09:53 blkio.io_service_bytes
-r--r--r-- 1 root root 0 Aug 28 09:53 blkio.io_serviced
-r--r--r-- 1 root root 0 Aug 28 09:53 blkio.io_service_time
-r--r--r-- 1 root root 0 Aug 28 09:53 blkio.io_wait_time
--w------- 1 root root 0 Aug 28 09:53 blkio.reset_stats
-r--r--r-- 1 root root 0 Aug 28 09:53 blkio.sectors
-r--r--r-- 1 root root 0 Aug 28 09:53 blkio.time
-rw-r--r-- 1 root root 0 Aug 28 09:53 blkio.weight
-rw-r--r-- 1 root root 0 Aug 28 09:53 blkio.weight_device
-rw-r--r-- 1 root root 0 Aug 28 09:53 cgroup.clone_children
--w--w--w- 1 root root 0 Aug 28 09:53 cgroup.event_control
-rw-r--r-- 1 root root 0 Aug 28 09:53 cgroup.procs
-r--r--r-- 1 root root 0 Aug 28 09:53 cpuacct.stat
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuacct.usage
-r--r--r-- 1 root root 0 Aug 28 09:53 cpuacct.usage_percpu
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpu.rt_period_us
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpu.rt_runtime_us
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.cpu_exclusive
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.cpus
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.mem_exclusive
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.mem_hardwall
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.memory_migrate
-r--r--r-- 1 root root 0 Aug 28 09:53 cpuset.memory_pressure
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.memory_pressure_enabled
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.memory_spread_page
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.memory_spread_slab
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.mems
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.sched_load_balance
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpuset.sched_relax_domain_level
-rw-r--r-- 1 root root 0 Aug 28 09:53 cpu.shares
--w------- 1 root root 0 Aug 28 09:53 devices.allow
--w------- 1 root root 0 Aug 28 09:53 devices.deny
-r--r--r-- 1 root root 0 Aug 28 09:53 devices.list
-rw-r--r-- 1 root root 0 Aug 28 09:53 net_cls.classid
-rw-r--r-- 1 root root 0 Aug 28 09:53 notify_on_release
-rw-r--r-- 1 root root 0 Aug 28 09:53 release_agent
-rw-r--r-- 1 root root 0 Aug 28 09:53 tasks
cat cpu.rt_period_us
1000000
cat cpu.rt_runtime_us
950000
 
通過配置 cpu.rt_period_us 和 cpu.rt_runtime_us 就可以對 cgroup 中的程序組中的實時程序進行 CPU使用時間的控制.
 
資源控制例項
上面主要介紹資源的一些理論基礎, 下面通過一些例項演示如果通過 cgroup 來控制程序所使用的 CPU和記憶體 資源.
Linux對CPU 和 記憶體的控制有對應的 cgroup 子系統 cpuset 和 memory
 
例項: cgroup 中對其中 *子cgroup* 的CPU資源控制
對各個 *子cgroup* 的CPU佔用率進行控制主要依靠每個 *子cgroup* 的 cpu.shares 檔案
直接用實驗過程來說話, 其中加入了一些註釋.
# 安裝需要的軟體
apt-get install stress     # 讓CPU達到 100% 的壓力工具
apt-get install sysstat    # 檢視系統CPU, 記憶體, 磁碟, 網路等資源使用情況的工具
 
例項1 - 預設情況, A 和 B 各佔CPU總資源的 1/2
    掛載 cgroup 檔案系統 (注意加上 -o cpu 的選項)
    在 cgroup中建立 2個子cgroup A 和 B
    預設情況下, cgroup A 和 cgroup B 中的 cpu.shares 中的數值都是 1024
    在 A 和 B 中用 stress 工具使其 CPU佔用率達到 100%
    top 命令檢視 A 和 B 中程序分別佔用的 CPU (應該都是 50%)
 
# 掛載 cgroup 檔案系統
mount -t cgroup -o cpu cgroup /mnt/cgroup/
cd /mnt/cgroup
ls -l
total 0
-r--r--r-- 1 root root 0 Aug 28 11:29 blkio.io_merged
-r--r--r-- 1 root root 0 Aug 28 11:29 blkio.io_queued
-r--r--r-- 1 root root 0 Aug 28 11:29 blkio.io_service_bytes
-r--r--r-- 1 root root 0 Aug 28 11:29 blkio.io_serviced
-r--r--r-- 1 root root 0 Aug 28 11:29 blkio.io_service_time
-r--r--r-- 1 root root 0 Aug 28 11:29 blkio.io_wait_time
--w------- 1 root root 0 Aug 28 11:29 blkio.reset_stats
-r--r--r-- 1 root root 0 Aug 28 11:29 blkio.sectors
-r--r--r-- 1 root root 0 Aug 28 11:29 blkio.time
-rw-r--r-- 1 root root 0 Aug 28 11:29 blkio.weight
-rw-r--r-- 1 root root 0 Aug 28 11:29 blkio.weight_device
-rw-r--r-- 1 root root 0 Aug 28 11:29 cgroup.clone_children
--w--w--w- 1 root root 0 Aug 28 11:29 cgroup.event_control
-rw-r--r-- 1 root root 0 Aug 28 11:29 cgroup.procs
-r--r--r-- 1 root root 0 Aug 28 11:29 cpuacct.stat
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuacct.usage
-r--r--r-- 1 root root 0 Aug 28 11:29 cpuacct.usage_percpu
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.cpu_exclusive
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.cpus
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.mem_exclusive
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.mem_hardwall
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.memory_migrate
-r--r--r-- 1 root root 0 Aug 28 11:29 cpuset.memory_pressure
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.memory_pressure_enabled
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.memory_spread_page
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.memory_spread_slab
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.mems
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.sched_load_balance
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpuset.sched_relax_domain_level
-rw-r--r-- 1 root root 0 Aug 28 11:29 cpu.shares
--w------- 1 root root 0 Aug 28 11:29 devices.allow
--w------- 1 root root 0 Aug 28 11:29 devices.deny
-r--r--r-- 1 root root 0 Aug 28 11:29 devices.list
-rw-r--r-- 1 root root 0 Aug 28 11:29 net_cls.classid
-rw-r--r-- 1 root root 0 Aug 28 11:29 notify_on_release
-rw-r--r-- 1 root root 0 Aug 28 11:29 release_agent
-rw-r--r-- 1 root root 0 Aug 28 11:29 tasks
# 建立 子cgroup A 和 B
mkdir {A,B}
cat A/cpu.shares
1024
cat B/cpu.shares
1024
# 在 A 和 B 中分別通過 stress 工具使其CPU使用率達到 100%
echo ¥¥ > A/tasks  # 將當前的 SHELL 加入到 cgroup A中
stress -c 2    # 這裡-c 2 是因為測試機器是雙核, 要在2個核上都產生 100% 的CPU 佔用率
# 另外開啟一個 shell 視窗, 並將這個shell 加入到 cgroup B中
echo ¥¥ > B/tasks  # 將當前的 SHELL 加入到 cgroup B中
stress -c 2    # 在2個核上都產生 100% 的CPU 佔用率
# 再開啟一個 shell 視窗, 用top命令檢視 CPU佔用情況
top
top - 14:10:32 up 43 min,  3 users,  load average: 2.31, 1.24, 0.62
Tasks:  78 total,   5 running,  73 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   1887872 total,   114744 used,  1773128 free,    10472 buffers
KiB Swap:  3982332 total,        0 used,  3982332 free,    45068 cached
 PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND                                                                                                                      
3350 root      20   0  6524   92    0 R  49.9  0.0   0:08.73 stress                                                                                                                       
3351 root      20   0  6524   92    0 R  49.9  0.0   0:08.67 stress                                                                                                                       
3353 root      20   0  6524   92    0 R  49.9  0.0   0:07.35 stress                                                                                                                       
3354 root      20   0  6524   92    0 R  49.9  0.0   0:07.36 stress                    
# 檢視這 4 個stress 程序是否分別屬於 A 和 B
cat /mnt/cgroup/A/tasks
2945
3349
3350   <-- stress 程序
3351   <-- stress 程序
cat /mnt/cgroup/B/tasks
2996
3352
3353   <-- stress 程序
3354   <-- stress 程序
可以看出, A和B組中的 2個stress 程序的CPU使用率相加都是 100%,
由於我測試的電腦是雙核, top所看到的CPU最大使用率是 200%, 所以和預期一致, A和B組各佔CPU總資源的 1/2
 
例項2 - A group 佔用整體CPU資源的 2/3, B group 佔用整體CPU資源的 1/3
    環境同 例項1, 不再重新掛載 cgroup 檔案系統, 也不在重建 A 和 B
    A group 的 cpu.shares 檔案不變, 值為 1024
    B group 的 cpu.shares 檔案中的值改為 512, 這樣, 相當於B佔用CPU總資源的 1/3 (因為 512 / (512+1024) = 1/3)
    同例項1, 通過2個shell視窗, 分別是 A 和 B 的CPU使用率達到 100%, 然後通過 top 檢視CPU使用情況
 
# 在 B 中shell 視窗執行以下命令
cat B/cpu.shares
1024
echo 512 > B/cpu.shares
cat B/cpu.shares
512
stress -c 2
# 在 A 中 shell 視窗執行以下命令
stress -c 2
# 在第3個 shell 視窗, 也就是 非A, 非B 的那個 shell 視窗, 用 top 檢視cpu使用情況
top
top - 14:13:18 up 46 min,  3 users,  load average: 2.24, 1.92, 1.01
Tasks:  78 total,   5 running,  73 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   1887872 total,   114744 used,  1773128 free,    10488 buffers
KiB Swap:  3982332 total,        0 used,  3982332 free,    45068 cached
 PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND                                                                                                                      
3376 root      20   0  6524   88    0 R  66.6  0.0   0:06.29 stress                                                                                                                       
3377 root      20   0  6524   88    0 R  66.6  0.0   0:06.30 stress                                                                                                                       
3373 root      20   0  6524   88    0 R  33.3  0.0   0:04.33 stress                                                                                                                       
3374 root      20   0  6524   88    0 R  33.3  0.0   0:04.32 stress               
# 檢視這 4 個stress 程序是否分別屬於 A 和 B
cat /mnt/cgroup/A/tasks
2945
3375
3376    <-- stress 程序
3377    <-- stress 程序
cat /mnt/cgroup/B/tasks
2996
3372
3373    <-- stress 程序
3374    <-- stress 程序
很明顯, A 組中的2個程序佔用了CPU總量的 2/3 左右, B組中的2個程序佔用了CPU總量的 1/3 左右.
 
例項3 - 物理CPU的控制
上面的例項中, 雖然能夠控制每個組的CPU的總體佔用率, 但是不能控制某個組的程序固定在某個物理CPU上執行.
要想將 cgroup 繫結到某個固定的CPU上, 需要使用 cpuset 子系統.
首先, 檢視系統是否支援 cpuset 子系統, 也就是看核心編譯選項 CONFIG_CPUSETS 是否設為y
cat /boot/config-`uname -r` | grep -i cpusets
CONFIG_CPUSETS=y
我的測試系統是支援的, 如果你的系統不支援, 就需要重新編譯核心了.......
 
然後, 用下面的例子演示將 A 和 B中的 stress 都指定到1個CPU上後的情況
    解除安裝當前的 cgroup
    再次掛載 cgroup 檔案系統, 並指定 -o cpuset
    指定 A 的物理CPU為 0 (雙核CPU的每個核編號分別是 CPU0, CPU1)
    指定 B 的物理CPU也為 0
    重複 例項1 中的步驟, 觀察發生的變化
 
umount /mnt/cgroup
mount -t cgroup -o cpuset cgroup /mnt/cgroup/
cd /mnt/cgroup
ls -l
total 0
-rw-r--r-- 1 root root 0 Aug 28 14:39 cgroup.clone_children
--w--w--w- 1 root root 0 Aug 28 14:39 cgroup.event_control
-rw-r--r-- 1 root root 0 Aug 28 14:39 cgroup.procs
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.cpu_exclusive
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.cpus    <-- 這個就是設定關聯物理CPU的檔案
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.mem_exclusive
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.mem_hardwall
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.memory_migrate
-r--r--r-- 1 root root 0 Aug 28 14:39 cpuset.memory_pressure
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.memory_pressure_enabled
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.memory_spread_page
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.memory_spread_slab
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.mems
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.sched_load_balance
-rw-r--r-- 1 root root 0 Aug 28 14:39 cpuset.sched_relax_domain_level
-rw-r--r-- 1 root root 0 Aug 28 14:39 notify_on_release
-rw-r--r-- 1 root root 0 Aug 28 14:39 release_agent
-rw-r--r-- 1 root root 0 Aug 28 14:39 tasks
# 建立子cgroup A 和 B
mkdir {A,B}
cat A/cpuset.cpus   
         <--  預設是空的
echo 0 > A/cpuset.cpus
cat A/cpuset.cpus
0
echo 0 > B/cpuset.cpus   # 同樣, 設定B組也繫結到CPU0
# 當前Shell加入到 A組
echo ¥¥ > /mnt/cgroup/A/tasks
-bash: echo: write error: No space left on device
 
如果出現上述錯誤, 只需要再設定 /mnt/cgroup/A/cpuset.mems 即可. (參考: http://serverfault.com/questions/579555/cgroup-no-space-left-on-device)
# 同時設定 A 的 cpuset.cpus 和 cpuset.mems
echo 0 > A/cpuset.cpus
echo 0 > A/cpuset.mems
# B組也同樣設定
echo 0 > B/cpuset.cpus
echo 0 > B/cpuset.mems
# 將當前 shell 加入到 A組
echo ¥¥ > /mnt/cgroup/A/tasks   <-- 設定過 cpuset.mems 後, 就沒有出錯了
stress -c 2
# 再開啟一個Shell視窗, 並加入到 B組
echo ¥¥ > /mnt/cgroup/B/tasks
stress -c 2
# 再開啟第3個 shell 視窗, 用top命令檢視CPU使用情況
top
top - 15:13:29 up  1:46,  3 users,  load average: 1.01, 0.24, 0.12
Tasks:  78 total,   5 running,  73 sleeping,   0 stopped,   0 zombie
%Cpu(s): 50.0 us,  0.0 sy,  0.0 ni, 50.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   1887872 total,   117216 used,  1770656 free,    11144 buffers
KiB Swap:  3982332 total,        0 used,  3982332 free,    47088 cached
 PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND                                                                                                                      
3830 root      20   0  6524   92    0 R  25.0  0.0   0:04.96 stress                                                                                                                       
3831 root      20   0  6524   92    0 R  25.0  0.0   0:04.97 stress                                                                                                                       
3834 root      20   0  6524   92    0 R  25.0  0.0   0:03.56 stress                                                                                                                       
3833 root      20   0  6524   92    0 R  24.6  0.0   0:03.56 stress
從上面的結果可以看出, 雖然 stress 命令指定了 -c 2(意思是在2個CPU上執行), 但是由於A和B都只綁定了CPU0,
所以雖然是雙核的機器, 它們所佔用的CPU總量卻只有 100%, 而不是例項1 中的 200%.
 
如果將B組的物理CPU繫結到CPU1, 那麼應該所有 stress 的程序都佔用 50%, CPU資源的總量變為 200%.
下面將B組的物理CPU繫結為CPU1, 看看結果是否和我們的預期一樣.
# 在 B組的 shell 視窗中執行以下命令
echo 1 > /mnt/cgroup/B/cpuset.cpus
cat /mnt/cgroup/B/cpuset.cpus
1
stress -c 2
# 在 A組的 shell 視窗中執行以下命令
stress -c 2
# 在第3個shell視窗中用top命令檢視執行結果
top
top - 15:20:07 up  1:53,  3 users,  load average: 0.38, 0.83, 0.56
Tasks:  78 total,   5 running,  73 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   1887872 total,   117340 used,  1770532 free,    11168 buffers
KiB Swap:  3982332 total,        0 used,  3982332 free,    47088 cached
  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND                                                                                                                      
 3854 root      20   0  6524   88    0 R  49.9  0.0   0:03.76 stress                                                                                                                       
 3857 root      20   0  6524   92    0 R  49.9  0.0   0:02.29 stress                                                                                                                       
 3858 root      20   0  6524   92    0 R  49.9  0.0   0:02.29 stress                                                                                                                       
 3855 root      20   0  6524   88    0 R  49.6  0.0   0:03.76 stress
果然, 和預期一致. A組中的 stress 和 B組中的 stress 在各自的物理CPU上都佔用了 100% 左右的CPU使用率.
 
例項4 - cgroup 對使用的記憶體的控制
cgroup 對記憶體的控制也很簡單, 只要掛載cgroup時, 指定 -o memory
# 首先之前掛載的 cpuset 子系統
umount /mnt/cgroup
# 掛載cgroup 檔案系統, 指定 -o memeory
mount -o memory -t cgroup memcg /mnt/cgroup/
mount: special device memcg does not exist
 
出現以上錯誤的原因可能是因為debian系統中, 預設沒有啟動 cgroup 的memory子系統. 可以通過以下方法確認:
cat /proc/cgroups
#subsys_name    hierarchy    num_cgroups    enabled
cpuset    0    1    1
cpu    0    1    1
cpuacct    0    1    1
memory    1    1    0              <-- 這裡的 enabled 是 0
devices    0    1    1
freezer    0    1    1
net_cls    0    1    1
blkio    0    1    1
perf_event    0    1    1
 
為了預設啟用memory子系統, 可以設定 grub選項
vim /etc/default/grub
# 修改 GRUB_CMDLINE_LINUX=""  ==> GRUB_CMDLINE_LINUX="cgroup_enable=memory"
# 儲存後, 更新grub.cfg
update-grub
reboot
 
重啟之後, 發現 /proc/cgroups 中的memory已經 enabled, 並且也可以掛載 memcg了
cat /proc/cgroups
#subsys_name    hierarchy    num_cgroups    enabled
cpuset    0    1    1
cpu    0    1    1
cpuacct    0    1    1
memory    1    1    1
devices    0    1    1
freezer    0    1    1
net_cls    0    1    1
blkio    0    1    1
perf_event    0    1    1
# 掛載cgroup 的memory子系統
mount -t cgroup -o memory memcg /mnt/cgroup
ls -l /mnt/cgroup/   <-- 可以看到有很多 memory 相關的配置
total 0
-rw-r--r-- 1 root root 0 Aug 28 15:54 cgroup.clone_children
--w--w--w- 1 root root 0 Aug 28 15:54 cgroup.event_control
-rw-r--r-- 1 root root 0 Aug 28 15:54 cgroup.procs
-rw-r--r-- 1 root root 0 Aug 28 15:54 memory.failcnt
--w------- 1 root root 0 Aug 28 15:54 memory.force_empty
-rw-r--r-- 1 root root 0 Aug 28 15:54 memory.limit_in_bytes   <-- 限制記憶體使用的配置檔案
-rw-r--r-- 1 root root 0 Aug 28 15:54 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Aug 28 15:54 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Aug 28 15:54 memory.numa_stat
-rw-r--r-- 1 root root 0 Aug 28 15:54 memory.oom_control
-rw-r--r-- 1 root root 0 Aug 28 15:54 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Aug 28 15:54 memory.stat
-rw-r--r-- 1 root root 0 Aug 28 15:54 memory.swappiness
-r--r--r-- 1 root root 0 Aug 28 15:54 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Aug 28 15:54 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Aug 28 15:54 notify_on_release
-rw-r--r-- 1 root root 0 Aug 28 15:54 release_agent
-rw-r--r-- 1 root root 0 Aug 28 15:54 tasks
 
開始實驗:
    重啟系統 (為了保證記憶體的乾淨)
    掛載 memcg
    在掛載的 /mnt/cgroup 中建立 組A
    將當前shell 加入到 組A
    不限制組A的記憶體, 壓縮核心原始碼包, 並觀察壓縮前後記憶體的變化
    重複步驟 1 ~ 4
    限制組A的記憶體為 10MB, 再次壓縮核心原始碼包, 並觀察壓縮前後記憶體的變化
 
# 重啟系統
reboot
# 掛載 memcg
mount -t cgroup -o memory memcg /mnt/cgroup
# 建立 組A
mkdir /mnt/cgroup/A
# 將當前 shell 加入到組A
echo ¥¥ > /mnt/cgroup/A/tasks
# 測試不限制記憶體時, 記憶體的使用情況, 這裡不用linux原始碼也可以, 但最好用個大點的資料夾來壓縮, 以便更容易看出記憶體的變化.
free -m; tar czvf linux-source-3.2.tar.gz /path/to/linux-source-3.2/ > /dev/null; free -m;
             total       used       free     shared    buffers     cached
Mem:          1843        122       1721          0          9         43
-/+ buffers/cache:         68       1774
Swap:         3888          0       3888
             total       used       free     shared    buffers     cached
Mem:          1843       1744         99          0         26       1614
-/+ buffers/cache:        104       1739
Swap:         3888          0       3888
# 重啟系統
reboot
# 掛載 memcg
mount -t cgroup -o memory memcg /mnt/cgroup