Cgroup簡介

本文轉載於:http://edsionte.com/techblog/archives/4314


Cgroup(Control Groups)是這樣一種機制:它以分組的形式對進程使用系統資源的行爲進行管理和控制。也就是說,用戶通過cgroup對所有進程進行分組,再對該分組整體進行資源的分配和控制。

1 Cgroup的結構

cgroup中的每個分組稱爲進程組,它包含多個進程。最初情況下,系統內的所有進程形成一個進程組(根進程組),根據系統對資源的需求,這個根進程組將被進一步細分爲子進程組,子進程組內的進程是根進程組內進程的子集。而這些子進程組很有可能繼續被進一步細分,最終,系統內所有的進程組形成一顆具有層次等級(hierarchy)關係的進程組樹。如下圖:


由於進程組可以被進一步劃分,因此一個進程可能處於多個進程組中,但這些進程組必然不處於同一層級中。

另外,如果某個進程組內的進程創建了子進程,那麼該子進程默認與父進程處於同一進程組中。也就是說,cgroup對改進程組的資源控制同樣作用於子進程。

2 subsystem

cgroup是一種對進程資源管理和控制的統一框架,它提供的是一種機制(mechanism),而具體的策略(policy)是通過子系統(subsystem)來完成的,子系統是cgroup對進程組進行資源控制的具體行爲。機制和策略是Linux操作系統中一種經典的設計思想,所謂機制就是“我要提供哪種功能”,而策略則是“我要怎樣來實現這種功能”。

cgroup中每個子系統都代表一種類型的資源,具體如下:

1) cpu子系統:該子系統爲每個進程組設置一個使用CPU的權重值,以此來管理進程對cpu的訪問。

2) cpuset子系統:對於多核cpu,該子系統可以設置進程組只能在指定的核上運行,並且還可以設置進程組在指定的內存節點上申請內存。

3) cpuacct子系統:該子系統只用於生成當前進程組內的進程對cpu的使用報告。

4) memory子系統:該子系統提供了以頁面爲單位對內存的訪問,比如對進程組設置內存使用上限等,同時可以生成內存資源報告

5) blkio子系統:該子系統用於限制每個塊設備的輸入輸出。首先,與CPU子系統類似,該系統通過爲每個進程組設置權重來控制塊設備對其的I/O時間;其次,該子系統也可以限制進程組的I/O帶寬以及IOPS。

6) devices子系統:通過該子系統可以限制進程組對設備的訪問,即該允許或禁止進程組對某設備的訪問。

7) freezer子系統:該子系統可以使得進程組中的所有進程掛起。

8) net-cls子系統:該子系統提供對網絡帶寬的訪問限制,比如對發送帶寬和接收帶寬進程限制。

如果要實現子系統對所屬進程組的資源控制,那麼就要實現該子系統對應的鉤子函數。這個關係與虛擬文件系統類似,VFS提供統一的用戶接口,而具體的文件操作則通過文件系統(比如ext3)對鉤子函數的實現。具體關係如下圖:


由圖可以看出,cgroup在用戶態提供統一的用戶接口,而每個子系統對資源的控制功能則通過其鉤子函數實現。這樣使得cgroup在上層是一個統一的框架,而下層則可以實現多種資源的控制。每個子系統的鉤子函數如下:

1 struct cgroup_subsys {
2         struct cgroup_subsys_state *(*css_alloc)(struct cgroup *cgrp);
3         int (*css_online)(struct cgroup *cgrp);
4         void (*css_offline)(struct cgroup *cgrp);
5         void (*css_free)(struct cgroup *cgrp);
6  
7         int (*can_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
8         void (*cancel_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
9         void (*attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
10         void (*fork)(struct task_struct *task);
11         void (*exit)(struct cgroup *cgrp, struct cgroup *old_cgrp,
12                      struct task_struct *task);
13         void (*bind)(struct cgroup *root);
14         …… ……
15 }

3 cgroup文件系統

cgroup在Linux內核中是以文件系統的形式存在的,不過cgroup對應的這種文件系統與proc文件系統類似,都是隻存在於內存中的“虛擬”文件系統。既然如此,就可以通過mount命令創建一個cgroup實例。

1 $ sudo mount -t cgroup -o memory memory_cgroup /dev/cgroup/

即在/dev/cgroup/下創建了一個memory子系統。接下來就可以通過:

1 $ cat /proc/filesystems | grep cgroup

可看到系統有了cgroup類型的文件系統。

當創建了一個cgroup實例後,對應的掛載點下會有一些文件,這些文件是用戶與cgroup進行交互的接口。由於cgroup位於VFS層之下,因此用戶可以通過統一的文件操作接口去讀取或設置子系統的參數,當然也可以直接使用echo或者cat等命令。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章