瞭解cgroups

什麼是cgroup?

cgroup是control group的縮寫,字面意思是控制組,控制什麼? 什麼組? 操做系統是資源管家,爲進程分配各類資源,這些資源有CPU, 內存,塊設備等。如何爲一組進程(一個進程是一組進程的特例)對資源的使用進行量化記帳和限制?cgroup就是解決這個問題的,提供一個統一的機制,各子系統根據這個機制實現自身控制策略。css

進程組是如何組織的? 答案:層級 (hierarchy)。進程按層級組織,各子系統(subsystem)按照自身資源分配策略在層級樹上進行資源分配。打個比方,每一個人像是一個進程,有戶口所在地如中國X省Y市,戶籍就是進程組,有三個層級國省市,社會有各類資源好比教育子系統,假如我是Y市某個學校的學生,那麼教育部門就會給這個學校分配老師和設施等資源。html

爲何須要cgroup?

舉個來自內核文檔(Documentation/cgroup-v1/cgroups.txt)中的栗子。試想,一個大學的服務器有不一樣用戶:學生,教授和系統任務。那這個服務器的資源可能須要這樣安排。CPU:linux

CPU :          "Top cpuset"
                       /       \
               CPUSet1         CPUSet2
                  |               |
               (Professors)    (Students)

               In addition (system tasks) are attached to topcpuset (so 
               that they can run anywhere) with a limit of 20%

內存:算法

Memory : Professors (50%), Students (30%), system (20%)

磁盤:數組

Disk : Professors (50%), Students (30%), system (20%)

網絡:瀏覽器

Network : WWW browsing (20%), Network File System (60%), others (20%)
                               / \
               Professors (15%)  students (5%)

好比瀏覽器firefox走的WWW服務,管理員能夠寫腳本程序知道哪類用戶教授仍是學生在使用firefox, 而後作以下控制:服務器

# echo browser_pid > /sys/fs/cgroup/<restype>/<userclass>/tasks

假如管理員體察民情,到了晚上,想給學生給多網絡資源,好讓學生能夠玩網絡遊戲放鬆一下。管理能夠在網絡子系統裏新建一個資源組,放寬流量限制,暫時把學生啓動的進程放到新建的資源組裏:網絡

# echo pid > /sys/fs/cgroup/network/<new_class>/tasks
       (after some time)
       # echo pid > /sys/fs/cgroup/network/<orig_class>/tasks

層級,子系統,cgroup和進程之間的關係?

這個文檔有配圖有文字講的比較清楚:Relationships Between Subsystems, Hierarchies, Control Groups and Tasks框架

  1. 一個層級能夠附加一個或多個子系統。例如,層級cpu_mem_cg有兩個子系統CPU和內存。
/cpu_mem_cg   |    <-------------CPU
              +-----/cg1       |   <-------------Memory
              +-----/cg2       |
  1. 一個子系統(如CPU)不能夠同時附加到兩個不一樣的層級中。例如,CPU子系統已經附加到了層級cpu_cg中,就不能再附加到另外一個層級cpu_mem_cg中。
  2. 每一個層級在新建時,都有一個default cgroup, 也叫root cgroup, 系統全部進程會被天然地加入root cgroup。在同一個層級中,一個進程只能屬於一個cgroup中,例如cpu_mem_cg層級有兩個cgroup: cg1和cg2,進程A不能同在cg1和cg2中。固然,一個進程能夠被添加到多個cgroup中,只要這些cgroup在不一樣的層級當中,好比層級cpu_cg->cg1和層級mem_cg->cg1,進程A能夠同時被添加到兩個cg1中。
  3. 子進程建立之初,繼承父進程的層級關係。但以後,關係能夠刪除,或改變。

cgroup是怎麼實現的?

雖然2015年Tejun重寫了cgroup v2, 可是cgroup v1版的文檔仍是有參考意義。主流發行版尚未用那麼新的內核,應該還都在使用cgroup v1。這裏簡單摘錄一下cgroup-v1文關於實現的文檔。ide

cgroup在內核中是這樣作的:

  • 每一個task有個指針指向css_set。css,即cgroup subsystem state。
  • css_set有一個指針數組,每一個指針指向cgroup_subsys_state對象。每一個對象表明一個子系統,可順着css_set -> cgroup_subsys_state指針找到進程所在的cgroup。
  • cgroup hierarchy filesystem 能夠mount上,用戶經過操做文件系統的方式使用cgroup。
  • 你能夠查看哪些進程(PID)被添加到了某個cgroup中。 cgroup的實現須要在內核各自系統中插入一些hook,好比:在init/main.c中,初始化root cgroups 和 css_set; 在fork()/exit()中,把任務附加/或從css_set中移除。

cgroup實現了相似procfs內存文件系統,即cgroup文件系統。掛載時,默認狀況下, cgroup文件系統會把全部子系統添加到層級中。用戶能夠經過掛載參數如mount -t cgroup -o cpu cgroup /sys/cgroup/cpu來選擇附加到層級中的子系統。

其實內核文檔對實現講的並不清楚,可參考這個博客Cgroup框架分析

blkio子系統

cgroups 子系統有多種, 如cpu, memory, 更全介紹參考Cgroup簡介-概述。筆者暫時只對blkio子系統感興趣。blkio資源控制模式有兩種: weight 和 bandwidth limit, 即便權重,或帶寬(iops)限制。權重的方式只有在IO調度器爲cfq時纔有用,可是目前blk-mq設備不支持任何調度器。

IO相關的還有cgroup writeback, 由於回寫跟內存子系統和blkio子系統都有關係。值得一提的是該功能須要文件系統的支持,目前ext4和btrfs能夠支持。

這部分後面須要研究下限流算法和代碼。

相關文章
相關標籤/搜索