RHELサーバにおいて、プロセスのCPU使用率がアクセス集中、処理中などで上昇し負荷が高くなることがあると思います。
CPUの負荷が上がるとサーバログイン後のレスポンスが遅かったり、他のプロセスにも影響を及ぼし悪循環を起こす原因にもなります。
このようにCPU負荷が高いプロセスのCPU使用率を一時的に下げる方法を解説します。
これは、cgroups(コントロールグループ)を使用してCPUを制限する方法になります。
サーバを再起動できなかったり、障害切り分けなどで活用できる便利な方法です。
この方法は、一時的に特定のプロセスに対してCPU使用率を制限するので設定を簡単に戻すこともできます。
また、サーバ再起動で容易にCPU利用率の制限を解除(設定を元に戻す事が)できます。
cgroups(コントロールグループ)について
細かい話は省略しますが、Linuxのカーネルを利用して、プロセスのリソースを階層的に制御・制約するための機能になります。
一般的には、「/sys/fs/cgroup/」にファイルシステムをマウントし、その配下の階層でリソースを制御します。
cgroupsは、特定のプロセスグループに対して、CPUだけではなく、メモリ、ディスクI/Oなどのリソースも制限できます。
※後程、画像を使って解説しますので、概要については深く知らなくても設定できますのでご安心ください。
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を利用できるか?の確認については以下になります。
mount -l |grep cgroup
->cgroupが表示されていれば「cgroup-v1」が利用できることを意味します。
cgroupsが利用できることが確認できれば、特定のプロセスに対してのCPU使用率を下げる手順を解説します。
cgroups-v1でCPU使用率を下げる方法
1.利用用途
- 特定のプロセスが高負荷となってCPU使用率を圧迫したとき一時的な回避策として利用
- プロセスは「1つ」か「2つ」ぐらいに絞ってCPU使用率を下げる場合に利用
2.CPU使用率を下げる事例
設定方法を分かりやすくするためにシンプルなケースで解説します。
■サーバの状態
CPU数 | 1 「CPU0」 |
|
高負荷プロセス数 | 1 「高負荷プロセス1」=「PID:1661」 |
ーー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-v1でCPU使用率を下げる手順
1CPU(cpu0)のサーバで「PID:1661」のCPU負荷を下げます。
->「PID:1661」のcpu0での使用率を「100%」から「50%」に下げます。
3-1「/sys/fs/cgroup/cpu」配下にディレクトリ作成
何でもよいですが、仮に「test」というディレクトリを作成します。
ディレクトリを作成すると、その配下にリソースを制御するためのファイルが複数作成されます。
mkdir /sys/fs/cgroup/cpu/test
3-2「cpu.cfs_period_us」と「cpu.cfs_quota_us」にCPU負荷軽減値(マイクロ秒)を設定
「cpu.cfs_period_us」と「cpu.cfs_quota_us」ファイルは、3-1でディレクトリを作成するとその配下に自動で作成さます。
「cpu.cfs_period_us」はプロセスグループが一定のCPU時間を取得できる期間を指定するためのパラメータになります。
「cpu.cfs_quota_us」はプロセスグループが一定のCPU時間を超えないように制約をかけるためのパラメータになります。
echo "1000000" > /sys/fs/cgroup/cpu/test/cpu.cfs_period_us
->デフォルト値:「cpu.cfs_period_us」=10000(0.1秒)
echo "500000" > /sys/fs/cgroup/cpu/test/cpu.cfs.quota_us
->デフォルト値:「cpu.cfs_quota_us」=-1(制限無)
「cpu.cfs_period_us」が1000000(1秒)で、「cpu.cfs_quota_us」が500000(0.5秒)とした場合対象のcgroup内のプロセスグループは1秒の期間内で最大0.5秒までのCPU利用が許可されます。
1CPUの場合
0.5秒/1秒=0.5(50%)となりCPU使用率が最大50%まで許可する設定を行いました。
「cpu.cfs_period_us」を設定する場合「1000000(1秒)」にするとCPU使用率の制限をするときに「cpu.cfs_quota_us」の設定値の考え方がシンプルに行えます。
今回の1CPUのケースでは
仮に「cpu.cfs_quota_us」の値を「300000(0.3秒)」とすると「0.3秒/1秒=0.3(30%)」となりCPU使用率が最大30%まで許可する設定になります。
3-3「PID:1661」プロセスにCPU使用率の制限設定
「3-2」で設定したCPU使用率の制限値を「PID:1661」のプロセスにセットしてCPU利用率を「100%から50%へ」下げます。
echo "1661" > /sys/fs/cgroup/cpu/test/cgroup.procs
->「3-1」で作成したディレクトリ(test)配下に「cgroup.procs」ファイルが存在しており、このファイルに「PID:1661」のプロセスIDを登録すると、「3-2」で設定したCPU使用率の制限値が適用されます。
設定後のCPU使用率の制限結果は、上記「2.CPU使用率を下げる事例」を確認ください。
4.CPU使用率の制限解除方法
CPU使用率の制限をするために「 /sys/fs/cgroup/cpu/test/」ディレクトリを作成しました。
このディレクトリ配下で設定したCPU使用率の制限値を同ディレクトリ配下の「cgroup.procs」ファイルに「PID:1661」を登録することでCPU制限をかけています。
今回、「PID:1661」のプロセスに設定したCPU使用率の制限を解除します。
echo "1661" >> /sys/fs/cgroup/cpu/cgroup.procs
「 /sys/fs/cgroup/cpu/test/cgroup.procs」に登録した「PID:1661」をCPU使用率の制限をかけていない「 /sys/fs/cgroup/cpu/cgroup.procs」へ移動させることでCPU使用率の制限は解除されます。
※移動元に登録した「PID:1661」はPIDを移動することで移動元から「PID:1661」の登録は消え移動元の「PID:1661」をわざわざ削除する必要はありません。
■補足
cgroupsは階層的に制御するため「/sys/fs/cgroup/cpu/」ディレクトリが起点となります。
「/sys/fs/cgroup/cpu/cgroup.procs」ファイルにはサーバ上で起動しているすべてのPIDが登録されています。
「/sys/fs/cgroup/cpu/」配下の「cpu.cfs_quota_us」ファイルなどでCPU使用率の制限をかけるとサーバ上で起動しているすべてのプロセスに制限がかかるので注意してください。
CPUの制限をかけたい場合は、「/sys/fs/cgroup/cpu/」配下にフォルダを作成し、そのフォルダ配下で制限をかけるようにしてください。
新しいプロセスを起動させると「/sys/fs/cgroup/cpu/cgroup.procs」ファイルにPIDが反映され、今回のように「/sys/fs/cgroup/cpu/test/cgroup.procs」へPIDを移動させると「/sys/fs/cgroup/cpu/cgroup.procs」からPIDは消えます。
※「 /sys/fs/cgroup/cpu/test/cgroup.procs」に登録がなくなれば、作成した「test」ディレクトリを削除できます。
rmdir /sys/fs/cgroup/cpu/test
cgroups-v1のまとめ
- 「cgroups」は階層構造でCPUなどのリソースを制限
- サーバ上で「cgroups-v1」利用可否の確認方法
# mount -l |grep cgroup - CPU制限をかけるPIDのCPU使用率を決定
例
cpu.cfs_period_us=1000000マイクロ秒(1秒)
->1秒にすることを推奨
cpu.cfs.quota_us=【制限値】(マイクロ秒)
->この値でCPU使用率を決める
サーバが1CPUの場合
【制限値】=500000 CPU利用率50%に制限
【制限値】=300000 CPU利用率30%に制限 - 「cgroups-v1」でCPU使用率の制限をする手順
# mkdir /sys/fs/cgroup/cpu/【ディレクトリ名】
# echo "1000000" > /sys/fs/cgroup/cpu/【ディレクトリ名】/cpu.cfs_period_us
# echo "【制御値(マイクロ秒)】" > /sys/fs/cgroup/cpu/【ディレクトリ名】/cpu.cfs.quota_us
# echo "PID" > /sys/fs/cgroup/cpu/【ディレクトリ名】/cgroup.procs - CPU使用率の制限解除方法
# echo "PID" >> /sys/fs/cgroup/cpu/cgroup.procs
補足
「/sys/fs/cgroup/cpu/【ディレクトリ名】/cgroup.procs」ファイルにPIDの登録がない場合は、「/sys/fs/cgroup/cpu/【ディレクトリ名】」ディレクトリを削除できます。
# rmdir /sys/fs/cgroup/cpu/【ディレクトリ名】
コメント