Cgroup 研究报告
Control Groups (Cgroups) 是 Red Hat Enterprise Linux 6 (以后簡稱 RHEL6) 提供的一項內核功能。Cgroup是將任意進程進行分組化管理的內核功能。
Cgroup提供了一個cgroup虛擬文件系統,作為進行分組管理和各子系統設置的用戶接口。因此,要使用cgroup,必須先掛載cgroup文件系統:
我們可以使用 Cgroups 為任務(進程)分配資源,例如 CPU 時間、系統內存、網絡帶寬等。我們可以對 Cgroups 進行監控,禁止 Cgroups 控制下的進程訪問某些資源,還可以在一個運行中的系統中對 Cgroups 動態地進行配置。cgconfig ( control group config ) 是一項系統服務,它可以根據配置文件創建 Cgroups,我們可以通過它在每次重啟操作系統之后保持一致的 Cgroups 配置。
Cgroup子系統
Cgroups 的組織結構為層次體系(目錄樹),Cgroups有多棵目錄樹,每棵樹對應一個或多個子系統(一個子系統表示一個單一的資源)。目前Cgroups提供了9個子系統:
- blkio- 該子系統限制塊設備的輸入輸出訪問;
- cpu- 該子系統調度cgroup中進程的cpu訪問;
- cpuacct- 該子系統生成cgroup中的任務使用cpu資源的報告;
- cpuset- 該子系統用于將cpu和內存節點指定給cgroup中的任務;
- devices- 該子系統用于限制cgroup中任務對設備的訪問權限;
- freezer- 該子系統可以暫停和繼續cgroup中的任務
- memory- 該子系統用于設定cgroup中任務使用的內存限額,并生成內存資源報告
- net_cls- network classifer cgroup使用等級標識符classid標記網絡數據包
- net_prio- 該子系統可以動態設置每個網卡的優先級
Cgroup層級
/cgroup(或者/sys/fs/cgroup)根目錄下的每個文件夾都是一個層級,通常的默認配置喜歡把子系統(如blkio)掛載到同名(如blkio)的層級上,這樣我們通常可以在/cgroup(或者/sys/fs/cgroup)根目錄下看到幾個名為blkio, cpu, cpuacct, cpuset, memory, devices的文件夾,這些文件夾就是一個個層級,層級上再掛載子系統。其實層級的名字可以隨便起哦,層級名不需要和子系統相同。可以把多個子系統掛到一個層級上(類似于多個設備同時掛載到一個目錄上),但是一個子系統不能掛到多個層級上,會提示already mounted or busy(類似于不能把一個設備同時掛載到多個目錄下)。
(1) 一個層級結構可以關聯一個或多個子系統(結果是,cpu和?memory子系統都掛載到一個層級名為cpu_mem_cg的層級上了)
?
(2) 任何單個子系統不可以被掛載到兩個及以上的層次結構(結果是,cpu子系統永遠無法附加到兩個不同的層級中)??
(3) 一個任務不能同時屬于同一個層次結構中的兩個 cgroup。
?
(4) 當 cgroups 中的一個任務 fork 出一個新任務時,新任務自動繼承其父任務的 cgroup 關系。但是,新任務與父任務之間是完全獨立的,新任務可以被移動到其他的 cgroups 。
?
Cgroup創建層級實例
(1) 首先創建一個目錄,作為層級結構的根:
mkdir /sys/fs/cgroup/cpu_and_mem(2) 接著掛載cgroup相應的子系統到該層次結構下:
mount -t cgroup -o cpu,cpuset,memory cpu_and_mem /sys/fs/cgroup/cpu_and_mem(3) 使用lssubsys來查看當前已經掛載了的子系統:
# lssubsys -amcpu,cpuset,memory /sys/fs/cgroup/cpu_and_memblkiocpuacctdevicesfreezer(4) 修改掛載的子系統,如現要將cpu_and_mem組也關聯到cpuacct中:
mount -t cgroup -o remount,cpu,cpuacct,cpuset,memory cpu_and_mem /sys/fs/cgroup/cpu_and_mem(5) 如果要刪除一個層級結構(目錄樹),直接umount相應的掛載點:
umount /sys/fs/cgroup/cpu_and_memCgroup創建進程組實例
上面,已經創建了一個層級結構,即進程組的父目錄,接下來就可以在該結構下創建group了。
(1) 創建組
mkdir /sys/fs/cgroup/cpu/lab1/group1mkdir /sys/fs/cgroup/cpuset/lab1/group1(2) 此時,cpu/lab1/group1的目錄里已經自動生成了許多文件,文件名前綴為cgroup的是由cgroup的基礎結構提供的特殊文件;前綴為cpu的是由cpu子系統提供的特殊文件。在這些特殊的文件中,最重要的是tasks文件,其記錄了屬于這個分組的PID。
(3) 在cgroup文件系統中,一個目錄就是一個分組。每個分組都是一系列線程的集合。cgroup/cpu, cgroup/blkio, cgroup/cpuset等等,這些目錄是每個子系統的根目錄,其tasks默認包含了當前系統所有進程的PID。不過,當cpu,cpuset,blkio等目錄下又有子目錄時,子目錄有自己的tasks,此時,父tasks會遷移一些進程到子tasks里去
Cgroup虛擬文件系統的掛載與卸載
(1) 可以通過/proc/cgroups查看系統支持的cgroup子系統,其中hierarchy項為0表明該子系統尚未掛載,非0表示已經掛載。若hierarchy項值相同的子系統表明這些子系統對應到同一層級結構(同一目錄)。?
?
(2) 可以使用lssubsys命令(libcgroup工具集)來更清晰的查看當前cgroup子系統的掛載情況和掛載點信息:
?
?
(3) 卸載cgroup子系統
a)先把各子系統目錄下的group依次從底層刪除,使用cgclear命令(也屬于libcgroup工具集)。
b)依次將lssubsys中的各個掛載點umount掉。
c)必須先刪除再umount,否則如果直接umount雖然目錄沒有了,但其實并沒有umount成功,通過/proc/cgroup可以看到它的hierarchy項非0。
d)如果沒有umount成功,應該先再把該子系統mount到一個目錄上,然后依次把沒有rmdir的目錄先全部rm了,再umount。
(4) 掛載cgroup子系統??
添加子目錄 創建一個cgroup,在剛才mount的目錄下:
mkdir /cgroup/cgtest這樣就創建了一個cgroup(該操作相對的是rmdir,即只有把該cgroup內的tasks移到top group才能真正將一個cgroup刪除掉),此時可以看到新目錄下已經有許多文件了。
libcgroup工具
libcgroup工具集安裝
使用cgroup的最簡單的方法是安裝libcgroup工具集。雖然可以使用shell命令來掛載和設定cgroup。但是,使用libcgroup工具可簡化過程并擴展功能。
redhat系:
debian系:
sudo apt-get install cgroup-bincgroup服務的啟動和停止(cgroup啟動時會自動讀取配置文件/etc/cgconfg.conf,根據其內容創建和掛載指定的cgroup子系統):
service cgconfig start|stopcgconfig配置文件分析
/etc/cgconfig.conf是cgroup配置工具libcgroup用來進行cgroup組的定義,參數設定以及掛載點定義的配置文件,主要由mount和group兩個section構成。 (1) mount section的語法格式如下:
mount { <controller> = <path>; ... }controller:內核子系統的名稱
path:該子系統的掛載點
舉個列子:
mount { cpuset = /cgroup/red; }上面定義相當于如下shell指令:
mkdir /cgroup/red mount -t cgroup -o cpuset red /cgroup/red(2) group section的格式如下:
group <name> { [<permissions>] <controller> { <param name> = <param value>; … } … }name: 指定cgroup的名稱
permissions:可選項,指定cgroup對應的掛載點文件系統的權限,root用戶擁有所有權限。 controller:子系統的名稱
param name 和 param value:子系統的屬性及其屬性值
舉個列子:
group daemons/www { ## 定義daemons/www(web服務器進程)組 perm { ## 定義這個組的權限task {uid = root;gid = webmaster;}admin {uid = root;gid = root;}}cpu { ## 定義cpu子系統的屬性及其值,即屬于詞組的任務的權重為1000cpu.shares = 1000;}}上面的配置文件相當于執行了如下的shell命令:
mkdir /mnt/cgroups/cpu/daemons mkdir /mnt/cgroups/cpu/daemons/www chown root:root /mnt/cgroups/cpu/daemons/www/* chown root:webmaster /mnt/cgroups/cpu/daemons/www/tasks echo 1000 > /mnt/cgroups/cpu/daemons/www/cpu.sharesCgroup子系統介紹
blkio子系統
blkio子系統控制并監控cgroup中的任務對塊設備的I/O訪問。在部分這樣的偽文件中寫入值可限制訪問或者帶寬,且從這些偽文件中讀取值可提供I/O操作信息。
blkio.weight:?指定cgroup默認可用訪問塊I/O 的相對比例(加權),范圍在100~1000。這個值可由具體設備的blkio.weight_device參數覆蓋。
舉個列子:將cgroup訪問塊設備的默認加權設定為500
blkio.weight_device:指定對cgroup中可用的?具體設備?I/O訪問的相對比例(加權),范圍是100~1000。這個值的格式為主設備號:從設備號 權值。
舉個例子:為訪問/dev/sda的cgroup分配加權500
blkio.time:報告cgroup對具體設備的I/O訪問時間。條目有三個字段主設備號:從設備號 時間(ms)
echo 8:0 1500 > blkio.timeCPU子系統
CPU子系統調度對cgroup的CPU訪問。可根據以下參數調度對CPU資源的訪問,每個參數都獨立存在于cgroup虛擬文件系統的偽文件中。
cpu.shares:指定在cgroup中的進程可用的相對共享CPU時間的整數值。
舉個例子:在兩個cgroup中都將cpu.shares設定為1的任務將有相同的CPU時間,但在cgroup中將cpu.shares設定為2的任務可使用的CPU時間是在cgroup中將cpu.shares設定為1的任務可使用的CPU時間的兩倍。
cpu.rt_runtime_us:指定在某個時間段中cgroup中的任務對CPU資源的最長連續訪問時間。這個屬性是為了訪問一個cgroup中的進程獨占CPU時間。
舉個例子:如果cgroup中的任務應該可以每5秒中有4秒時間訪問CPU資源,需要將cpu.rt_runtime_us設定為4000000,并將cpu.rt_period_us設定為5000000。
cpu.rt_period_us:配合上例使用,設定時間段的長度。
cpuacct子系統
CPU Accounting(cpuacct)子???系???統???自???動???生???成??? cgroup 中???任???務???所???使???用???的??? CPU 資???源???報???告???,其???中???包???括???子???組???群???中???的???任???務???。
cpuacct.stat:報???告???這???個??? cgroup 及???其???子???組???群???中???的???任???務???使???用???用???戶???模???式???和???系???統???(內???核???)模???式???消???耗???的??? CPU 循???環???數???(單???位???由???系???統???中???的??? USER_HZ 定???義???)。
cpuacct.usage:報???告???這???個??? cgroup 中???所???有???任???務???(包???括???層???級???中???的???低???端???任???務???)消???耗???的???總??? CPU 時???間???(納???秒???)。
cpuacct.usage_percpu:報???告???這???個??? cgroup 中???所???有???任???務???(包???括???層???級???中???的???低???端???任???務???)在???每???個??? CPU 中???消???耗???的??? CPU 時???間???(以???納???秒???為???單???位???)。
cpuset
cpuset子系統為cgroup分配獨立CPU和內存節點。可根據以下參數指定每個cpuset,每個參數都在控制組群虛擬文件系統中有單獨的偽文件:
cpuset.cpus:指定允許這個cgroup中任務訪問的CPU。這是一個用都好分開的列表,使用小橫線(“-”)代表范圍。
舉個列子:echo 0-2,16 > cpuset.cpus 代表該cgroup可以使用CPU 0,1,2,16
cpuset.mems:指定允許這個cgroup中任務可訪問的內存節點。
總結
以上是生活随笔為你收集整理的Cgroup 研究报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: QEMU KVM 虚拟机移植之性能提高篇
- 下一篇: 深度优化LNMP之Nginx [2]