Maidsphere

2011.6.28

かんたんなcgroups(Control Groups)のはなし まずは,cgroupsって何か これはLinuxにおけるプロセスの資源管理用サブシステムです のこれらの資源を,プロセス(もしくはプロセスグループ)ごとに かなり詳細にチューニングできます cgroupsはカーネル2.6.24で初めてマージされてるので これ以前のカーネル(CentOS 5.6など)の場合は利用できないので注意が必要です また,搭載されているサブシステムによって 利用できる機能とそうでないものが発生しますので このあたりにも留意する必要があります # どのサブシステムが搭載されているかを簡単に判別する方法があります # これについては後述します つぎに,実際にcgroupsを使う方法について 使っているカーネルがcgroupsに対応しているか また,どのようなサブシステムが使えるかを把握しておく必要があります % dmesg | grep cgroup [ 0.000000] Initializing cgroup subsys cpuset [ 0.000000] Initializing cgroup subsys cpu [ 0.015177] Initializing cgroup subsys ns [ 0.015273] Initializing cgroup subsys cpuacct [ 0.015335] Initializing cgroup subsys devices [ 0.015387] Initializing cgroup subsys freezer [ 0.015415] Initializing cgroup subsys net_cls この場合は,cgroupsのcpuset・cpu・ns・cpuacct・devicesなどの 各サブシステムが利用可能です 各サブシステムの機能について,簡単にまとめておきます
cpuset
使用するCPUコアの指定
cpu
CPU時間の優先度の指定(指定した値に比例したCPU時間を割り当て)
cpuacct
CPU使用率の情報表示
memory
メモリ使用量の上限を指定
ns
名前空間への対応
devices
デバイスに対するアクセスコントロールリストの指定
freezer
プロセスの一時停止のサポート(対象のプロセスをSIGSTOPするのと同義)
net_cls
ネットワークI/Oの優先度の指定
blkio
ディスクI/Oの優先度の指定
なお,CPU使用率の設定はniceよりも詳細に指定できます cpuサブシステムを使う場合について,もう少し詳細に見ておきます # mkdir /dev/cgroup # mount -t cgroup -o cpu cgroup /dev/cgroup # ls -1 /dev/cgroup cgroup.procs cpu.shares notify_on_release release_agent sysdefault tasks 「-o」オプションで,利用するサブシステムを指定します 複数のサブシステムを利用する場合はコンマで区切ればOKです 利用可能なサブシステムをすべて利用する場合は 「cgroups」を指定するといいようです # pwd /dev/cgroup # mkdir janedoe # cd janedoe # ls -1 cgroup.procs cpu.shares notify_on_release tasks # cat cpu.shares 1024 このように,「janedoe」というプロセスグループに対応する設定を個別に作成できます このプロセスグループ名は任意に指定でき,またそのグループに属するプロセスも任意に指定できます あるグループに属するプロセスは,「tasks」というファイルの中身を見ればわかります このファイルに書き込まれているプロセスIDで判別することができます cpuサブシステムにおけるCPU使用率の調整は「cpu.shares」というファイルから行います このファイルに値を書き込むと,その値に応じたCPU使用率が割り振られます デフォルトはここで示したとおり1,024です この指定方法ですが,簡単に説明しておきます たとえば,cpu.sharesが1,024のグループAと,その2倍の2,048のグループBがあるとします このときは,グループAのプロセスはCPU使用率を33%利用します いっぽうグループBは67%です グループBがグループAの2倍のCPU使用率を受け取っていることがわかります このように,cpu.sharesの値を元にCPU使用率は比例配分されます 実際に,どのようにCPU使用率を調整するかについて ここから説明していきます このように,無限ループだけを行うシェルスクリプトを用意し それぞれ「cpu_jane.sh」と「cpu_john.sh」という名前で保存し,実行します # cat /root/cpu_jane.sh #!/bin/sh while true; do true; done # cat /root/cpu_john.sh #!/bin/sh while true; do true; done # /root/cpu_jane.sh & # /root/cpu_john.sh & このときのtopの結果はこのようになるはずです top - 13:32:43 up 36 min, 4 users, load average: 1.35, 0.40, 0.14 Tasks: 102 total, 4 running, 98 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 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2185 root 20 0 3952 556 464 R 49.8 0.1 0:38.33 cpu_jane.sh 2186 root 20 0 3952 556 464 R 49.8 0.1 0:33.63 cpu_john.sh 双方ともに,50%ずつCPU使用率を受け取っています この状態で,以下の操作をします まず,「johndoe」というプロセスグループを作成します # 「janedoe」はさっき作りましたね;D # できていない場合は,「johndoe」の手順と同様に作成できます # pwd /dev/cgroup # mkdir johndoe # ls janedoe johndoe janedoe: cgroup.procs cpu.shares notify_on_release tasks johndoe: cgroup.procs cpu.shares notify_on_release tasks つぎに,プロセスID 2185(cpu_jane.sh)を「janedoe」グループに また,プロセスID 2186(cpu_john.sh)を「johndoe」グループに属させます # /bin/echo 2185 > /dev/cgroup/janedoe/tasks # /bin/echo 2186 > /dev/cgroup/johndoe/tasks さいごに,「janedoe」グループのcpu.sharesを2,048にします # /bin/echo 2048 > /dev/cgroup/janedoe/cpu.shares # cat /dev/cgroup/janedoe/cpu.shares 2048 # cat /dev/cgroup/johndoe/cpu.shares 1024 さあて,topの結果は? top - 13:36:31 up 40 min, 4 users, load average: 2.07, 1.28, 0.55 Tasks: 103 total, 3 running, 100 sleeping, 0 stopped, 0 zombie Cpu(s): 99.0%us, 1.0%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2185 root 20 0 3952 556 464 R 67.2 0.1 2:35.74 cpu_jane.sh 2186 root 20 0 3952 556 464 R 32.6 0.1 2:22.37 cpu_john.sh 「janedoe」グループのcpu_jane.shが67%のCPU使用率をもらっていることがわかります 同様に,「johndoe」グループのcpu_john.shは33%しか使えていません このcgroupsを使うと,KVM上で動作する各VMについて かなり詳細に資源配分を調整できるようになります すごくフレキシブルな機構なので,いろいろ活用してみるといいと思います ちなみに,各ディストリビューションには「cgroup-bin」という この操作を簡単に行ってくれるユーティリティを詰め込んだパッケージが存在します このあたりを使ってみると,もっとプロセスの資源配分を楽に行えるようになると思います