今更だけど便利そうな機能なので勉強。
- http://docs.redhat.com/docs/ja-JP/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/ch01.html
- http://docs.redhat.com/docs/ja-JP/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/ch-Subsystems_and_Tunable_Parameters.html
- http://en.wikipedia.org/wiki/Processor_affinity
Red Hat Enterprise Linux 6 では、コントロールグループ と呼ばれる新たなカーネル機能を搭載しています。本ガイドでは、この機能を cgroup という略称で記載しています。cgroup により、ユーザーは、CPU 時間、システムメモリー、ネットワーク帯域幅などのリソースやそれらのリソースの組み合わせを、システム上で実行中のユーザー定義タスクグループ (プロセス) の間で割り当てることができるようになります。
RHEL6系の場合
# yum install libcgroup # service cgconfig start
関連するファイル
- /etc/init.d/cgconfig
- /etc/cgconfig.conf
- /etc/init.d/cgred
- /etc/cgrules.conf
cgconfig を起動すると/cgroup 以下にcgroup file systemがマウントされる。
# ls -1d /cgroup/* /cgroup/blkio /cgroup/cpu /cgroup/cpuacct /cgroup/cpuset /cgroup/devices /cgroup/freezer /cgroup/memory /cgroup/net_cls # cat /proc/mounts (snip) cgroup /cgroup/cpuset cgroup rw,relatime,cpuset 0 0 cgroup /cgroup/cpu cgroup rw,relatime,cpu 0 0 cgroup /cgroup/cpuacct cgroup rw,relatime,cpuacct 0 0 cgroup /cgroup/memory cgroup rw,relatime,memory 0 0 cgroup /cgroup/devices cgroup rw,relatime,devices 0 0 cgroup /cgroup/freezer cgroup rw,relatime,freezer 0 0 cgroup /cgroup/net_cls cgroup rw,relatime,net_cls 0 0 cgroup /cgroup/blkio cgroup rw,relatime,blkio 0 0 # cat /proc/cgroups #subsys_name hierarchy num_cgroups enabled cpuset 1 1 1 ns 0 1 1 cpu 2 1 1 cpuacct 3 1 1 memory 4 1 1 devices 5 1 1 freezer 6 1 1 net_cls 7 1 1 blkio 8 1 1 perf_event 0 1 1 net_prio 0 1 1
- コマンド
- cgcreate, cgdelete, cgset, cgclassify, cgexec, lscgroup, cgset, cgget, cgget -g cpuset / など
- プロセスの確認
- ps の -o cgroup の項目
- cat /proc/pid/cgroup
実験
# コントローラによっては必須パラメータを指定しておかないと、コントローラへのプロセスの割り当てが失敗するので注意。例えばcpuset ではcpuset.cpusとcpuset.mems が必須。
4コアのcpuのマシンで、hoge ユーザのプロセスを0にのみ割り当てる
- コントロールグループ名をtestで作成
- 設定できる値は自分のH/W情報を確認するか親コントローラの設定
- /cgroup/cpuset 以下のファイルの中身 を見て確認
# cgcreate cpuset:/test ### /cgroup/cpuset/test 以下が作成される # cgset -r cpuset.cpus=0 test # cgset -r cpuset.mems=0 ### or echoで書き込み
コントローラグループへのプロセスの移動
↑で設定したcpuset を適用する例
手動 で行う
1. cgclassify を使う
#### hoge ユーザ何か実行 $ perl -e '1 while 1' #### pid 調べる # pgrep -fl perl 27136 perl -e 1 while 1 # cgclassify -g cpuset:hoge 27136 # date 2012年 4月 15日 日曜日 14:52:35 JST
2. echo でpidをtasksに書き込む
redhatの例でもechoのリダイレクトが追記(>>)じゃなくて書き込み(>)になっているけど、既存のpid情報は消えるわけじゃなくて、実際には追記されるだけなので大丈夫。(通常のファイルじゃなくて cgroupファイルシステムの擬似ファイルだから?)
# echo 27136 > /cgroup/cpuset/test/tasks
- cgclassify 前後のsar -P ALL の結果
ループを回していたperlのプロセスがcpu3番からcpu0番に移動したのがわかる。
14時52分33秒 CPU %user %nice %system %iowait %steal %idle 14時52分34秒 all 0.00 25.00 0.50 0.25 0.00 74.26 14時52分34秒 0 0.00 0.00 0.99 0.00 0.00 99.01 14時52分34秒 1 0.00 0.00 0.00 0.00 0.00 100.00 14時52分34秒 2 0.00 0.00 1.94 0.97 0.00 97.09 14時52分34秒 3 0.00 100.00 0.00 0.00 0.00 0.00 14時52分34秒 CPU %user %nice %system %iowait %steal %idle 14時52分35秒 all 0.00 27.94 1.31 2.35 0.00 68.41 14時52分35秒 0 0.00 27.45 0.98 6.86 0.00 64.71 14時52分35秒 1 0.00 2.94 0.98 0.00 0.00 96.08 14時52分35秒 2 0.00 1.94 2.91 1.94 0.00 93.20 14時52分35秒 3 0.00 97.37 0.00 0.00 0.00 2.63 14時52分35秒 CPU %user %nice %system %iowait %steal %idle 14時52分36秒 all 0.00 23.64 0.71 0.00 0.00 75.65 14時52分36秒 0 0.00 100.00 0.00 0.00 0.00 0.00 14時52分36秒 1 0.00 0.00 0.00 0.00 0.00 100.00 14時52分36秒 2 0.00 0.00 1.96 0.00 0.00 98.04 14時52分36秒 3 0.00 0.00 0.00 0.00 0.00 100.00 14時52分36秒 CPU %user %nice %system %iowait %steal %idle 14時52分37秒 all 0.00 25.97 1.04 0.52 0.00 72.47 14時52分37秒 0 0.00 100.00 0.00 0.00 0.00 0.00 14時52分37秒 1 0.00 1.10 5.49 0.00 0.00 93.41 14時52分37秒 2 0.00 0.00 1.00 1.00 0.00 98.00 14時52分37秒 3 0.00 0.00 0.00 0.00 0.00 100.00
自動で行う
後述のcgred (/etc/cgrules.conf) で。
/etc/cgconfig.conf でコントローラの作成
cgcreate で作ったものはOS再起動 (/etc/init.d/cgconfig restart) で消えてしまうので、永続的に設定するなら/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; } group test { perm { task { uid = root; gid = root; } admin { uid = root; gid = root; } } cpuset { cpuset.cpus = 0; cpuset.mems = 0; } }
設定したら/etc/init.d/cgconfig restart。
cgredデーモンで自動的にプロセスをコントローラに移動
いちいちcgclassify コマンドをプロセスごとに実行なんてやってられないので、実際に使う場合はこの方法かな。/etc/cgrules.conf に設定して、cgred を起動しておく。/etc/security/limits.conf likeな感じ。
ユーザ、グループ、実行するプロセスごとに割り当てるコントローラの種類、コントローラグループを指定できる。
#<user> <controllers> <destination> #<user>:<process name> <controllers> <destination> # #john cpu usergroup/faculty/john/ #john:cp cpu usergroup/faculty/john/cp #@student cpu,memory usergroup/student/ #peter cpu test1/ #% memory test2/ #@root * admingroup/ #* * default/
cgclassify (or echo) , cgred がエラーになる場合
cpusetで必須のcpuset.cpus, cpuset,mems を指定しない状態で、cgclassify やcgredデーモンを動かしてもエラーになる。
# cgclassify -g cpuset:test 27742 Error changing group of pid 27742: No space left on device
cgredの場合は/var/log/messages にエラーが出る。
CGRE[27965]: Cgroup change for PID: 27969, UID: 503, GID: 503, PROCNAME: /usr/bin/perl FAILED! (Error Code: 50016)