「cgroups-v1」で、CPU負荷が高いプロセスのCPU利用率を一時的に下げる方法を解説しました。
今回、「cgroups-v2」の場合でCPU負荷を下げる方法を解説します。
「cgroups-v1」と「cgroups-v2」どちらを利用しているか見分け方
■見分け方
mount -l |grep cgroup
cgroup2が表示されていれば「cgroups-v2」が利用できることを意味します。
※cgroup2と表示されていなければ、「cgroups-v1」でありこちらを参照してください
cgroupsには、以下の2つバージョンがあります。
Control groups version 1 (cgroups-v1) ->RHEL8.1以前で利用可能※RHEL7もOK
Control groups version 2 (cgroups-v2) ->RHEL8.2以降で利用可能※RHEL9もOK
これらを利用するには、カーネル上で事前に設定しておく必要がありますが通常のOSインストールを実施していれば、cgroupsを利用できる状態なっています。
※すなわち、「/sys/fs/cgroup/」にファイルシステムがマウントされています。
cgroups-v2でCPU使用率を下げる方法
1.利用用途
- 特定のプロセスが高負荷となってCPU使用率を圧迫したとき一時的な回避策として利用
- プロセスは「1つ」か「2つ」ぐらいに絞ってCPU使用率を下げる場合に利用
2.CPU使用率を下げる事例
設定方法を分かりやすくするためにシンプルなケースで解説します。
■サーバの状態
CPU数 | 1 「CPU0」 |
|
高負荷プロセス数 | 1 「高負荷プロセス1」=「PID:1647」 |
ーーCPU使用率制限前ーー
ーーCPU使用率制限後ーー
■CPU使用率の制限効果
CPU |
設定前 | 1CPUに占める「高負荷プロセス1」の占有率が100% 「CPU0」使用率:100% 「高負荷プロセス1」のCPU利用率:100%(100%/1プロセス) |
設定後 | 1CPUに占める「高負荷プロセス1」の占有率が50% 「CPU0」使用率:50% 「高負荷プロセス1」のCPU利用率:50%(50/1プロセス) |
|
CPUの制限後の占有率 | CPU占有率が100%->50%軽減 CPU全体(1CPU)の1/2の占有率に改善 |
3.cgroups-v2でCPU使用率を下げるための事前設定
3-1「/sys/fs/cgroup/cgroup.controllers」ファイルに「cpu」と「cpuset」の登録確認
■確認方法
more /sys/fs/cgroup/cgroup.controllers
「/sys/fs/cgroup」階層において「cpu」と「cpuset」のコントローラーが利用できることを確認します。
この階層は最上位にあたる階層となります。
cgroupsは階層構造でリソースをコントールします。
※最上位層でリソースのコントロールは行いません。
これから「/sys/fs/cgroup」配下にディレクトリを作成してCPUをコントロールします。
CPUをコントロールするには、「cpu」と「cpuset」のコントローラーが下層の階層化で利用できるようにする必要があります。
下層の階層化(ディレクトリ配下)で「cpu」と「cpuset」のコントローラーを利用できるようにするためには上位層で利用できている必要があります。
上位層で「cpu」と「cpuset」コントローラーを利用できていると下層の階層へ継承することができます。
3-2「cpu」と「cpuset」のコントローラーを下層へ継承できるように登録
■登録方法
more /sys/fs/cgroup/cgroup.subtree_control
echo "+cpuset" >> /sys/fs/cgroup/cgroup.subtree_control
echo "+cpu" >> /sys/fs/cgroup/cgroup.subtree_control
->デフォルトで「cpu」は設定されており、登録は不要となります。
※実行しても上書きとなり問題ありません。
more /sys/fs/cgroup/cgroup.subtree_control
下層配下へ継承したくない場合は、コントローラーを削除することができます。
但し、デフォルトで登録があったものは削除できません。
今回の場合は、「cpu io memory pids」は削除できません。
「cpuset」は削除できます。
■削除方法※今回は実行しません。
echo "-cpuset" >> /sys/fs/cgroup/cgroup.subtree_control
3-3 CPU使用率を下げる環境を準備
「/sys/fs/cgroup/」配下に任意のディレクトリ(test)を作成します。その後、CPU使用率を下げたいCPUを指定します。
※CPUが1つの場合は無条件で設定します。
※CPUが2つ以上ある場合は、使用率をさげたいプロセスが使用するCPUを指定することができます。
■環境準備
mkdir /sys/fs/cgroup/test
ls /sys/fs/cgroup/test
more /proc/cpuinfo |grep processor
echo "0" > /sys/fs/cgroup/test/cpuset.cpus
->CPUは1つなので1つ目のCPUは「0」となります。
「more /proc/cpuinfo」の「processor」を参照
->CPUが複数ありそれらを指定したい場合はスペース区切りで指定します。
「echo "0 1 2" > /sys/fs/cgroup/test/cpuset.cpus
more /sys/fs/cgroup/test/cpuset.cpus
4.cgroups-v2でCPU使用率を下げる手順
「3.」で事前設定後、1CPU(cpu0)のサーバで「PID:1647」のCPU負荷を下げます。
->「PID:1647」のcpu0での使用率を「100%」から「50%」に下げます。
4-1「/sys/fs/cgroup/test/cpu.max」にCPU負荷軽減値(マイクロ秒)を設定
cpu.maxファイルでCPU帯域幅を設定します。設定方法は以下になります。
「【制限値】 【期間】」
->(スペース区切り)。単位はマイクロ秒。デフォルト値は「max 100000」
今回は、「【制限値】 【期間】」=「500000(0.5秒) 1000000(1秒)」とします。
■設定方法1
more /sys/fs/cgroup/test/cpu.max
echo "500000 1000000" > /sys/fs/cgroup/test/cpu.max
more /sys/fs/cgroup/test/cpu.max
■「500000(0.5秒) 1000000(1秒)」の場合
1秒ごとに0.5秒しかCPUが利用できません。
通常、1秒の処理があった場合、1秒で処理が終了します。
今回の設定だと、0.5秒しかCPUを実行できないので2秒かかって処理が終了します。これは、1秒間のなかで0.5秒しかCPUは利用していないことになります。
すなわち、1つのプロセスは50%のCPU使用率となって制限をかけることができます。
■「300000(0.3秒) 1000000(1秒)」の場合
1秒間のなかで0.3秒しかCPUを利用しないので、30%のCPU使用率となって制限をかけることができます。
期間は1000000(1秒)として制限値を調整するとCPU使用率制限は考えやすくなります。
4-2「PID:1647」プロセスにCPU利用率の制限設定
「4-1」で設定したCPU使用率の制限値を「PID:1647」のプロセスにセットしてCPU利用率を「100%から50%へ」下げます。
■設定方法2
echo "1647" > /sys/fs/cgroup/test/cgroup.procs
more /sys/fs/cgroup/test/cgroup.procs
->「3-3」で作成したディレクトリ(test)配下に「cgroup.procs」ファイルが存在しており、このファイルに「PID:1647」のプロセスIDを登録すると、「4-1」で設定したCPU使用率の制限値が適用されます。
設定後のCPU使用率の制限結果は、上記「2.CPU使用率を下げる事例」を確認ください
5.CPU使用率の制限解除方法
CPU使用率の制限をするために「 /sys/fs/cgroup/test/」ディレクトリを作成しました。
このディレクトリ配下で設定したCPU使用率の制限値(cpu.max)を同ディレクトリ配下の「cgroup.procs」ファイルに「PID:1647」を登録することでCPU制限をかけています。
今回、「PID:1647」のプロセスに設定したCPU使用率の制限を解除します。
■解除方法
echo "1647" >> /sys/fs/cgroup/cgroup.procs
more /sys/fs/cgroup/cgroup.procs |grep 1647
「 /sys/fs/cgroup/test/cgroup.procs」に登録した「PID:1647」をCPU使用率の制限をかけていない「 /sys/fs/cgroup/cgroup.procs」へ移動させることでCPU使用率の制限は解除されます。
※移動元に登録した「PID:1647」はPIDを移動することで移動元から「PID:1647」の登録は消え移動元の「PID:1647」をわざわざ削除する必要はありません。
■補足
cgroupsは階層的に制御するため「/sys/fs/cgroup/」ディレクトリが起点となります。
「/sys/fs/cgroup/cgroup.procs」ファイルにはサーバ上で起動しているすべてのPIDが登録されています。
「/sys/fs/cgroup/」配下の「cpu.max」ファイルなどでCPU使用率の制限をかけるとサーバ上で起動しているすべてのプロセスに制限がかかるので注意してください。
CPUの制限をかけたい場合は、「/sys/fs/cgroup/cpu/」配下にフォルダを作成し、そのフォルダ配下で制限をかけるようにしてください。
新しいプロセスを起動させると「/sys/fs/cgroup/cgroup.procs」ファイルにPIDが反映され、今回のように「/sys/fs/cgroup/test/cgroup.procs」へPIDを移動させると「/sys/fs/cgroup/cgroup.procs」からPIDは消えます。
※「 /sys/fs/cgroup/test/cgroup.procs」に登録がなくなれば、作成した「test」ディレクトリを削除できます。
■削除方法
rmdir /sys/fs/cgroup/test
cgroups-v2のまとめ
- 「cgroups」は階層構造でCPUなどのリソースを制限
- サーバ上で「cgroups-v2」利用可否の確認方法
# mount -l |grep cgroup - CPU制限をかけるPIDのCPU使用率を決定
cpu.max
「【制限値】 【期間】」(スペース区切り)。単位はマイクロ秒。
【制限値】=この値でCPU利用率を決める
【期間】=1000000(1秒)にすることを推奨
# echo "500000 1000000" > /sys/fs/cgroup/【ディレクトリ名】/cpu.max
例
サーバが1CPUの場合※【期間】=1000000(1秒)である事
【制限値】=500000 CPU利用率50%に制限
【制限値】=300000 CPU利用率30%に制限 - 「cgroups-v2」でCPU使用率の制限をする手順
# cat /sys/fs/cgroup/cgroup.controllers
# echo "+cpuset" >> /sys/fs/cgroup/cgroup.subtree_control
# echo "+cpu" >> /sys/fs/cgroup/cgroup.subtree_control
# mkdir /sys/fs/cgroup/【ディレクトリ名】
# echo "【CPU processor名】" > /sys/fs/cgroup/【ディレクトリ名】/cpuset.cpus
# echo "【制限値(マイクロ秒)】 1000000" > /sys/fs/cgroup/【ディレクトリ名】/cpu.max
# echo "PID" > /sys/fs/cgroup/【ディレクトリ名】/cgroup.procs - CPU使用率の制限解除方法
# echo "PID" >> /sys/fs/cgroup/cgroup.procs
補足
「/sys/fs/cgroup/【ディレクトリ名】/cgroup.procs」ファイルにPIDの登録がない場合は、「/sys/fs/cgroup/【ディレクトリ名】」ディレクトリを削除できます。
# rmdir /sys/fs/cgroup/【ディレクトリ名】
コメント