2.3.2. ユニットファイルの変更
Systemd サービスユニットファイルは、リソース管理に役立つ高レベルの設定パラメーターを多数提供します。これらのパラメーターは、カーネルで有効にする必要がある Linux cgroup コントローラーと通信します。これらのパラメーターを使用すると、CPU、メモリー消費、ブロック IO、さらに細かいユニットプロパティーを管理できます。
CPU の管理
CPU コントローラーはカーネルでデフォルトで有効になっているため、含まれるプロセスの数に関係なく、すべてのシステムサービスは同じ量の CPU 時間を受け取ります。このデフォルトの動作は、
/etc/systemd/system.conf
設定ファイルの DefaultControllers
パラメーターで変更できます。CPU 割り当てを管理するには、ユニット設定ファイルの Service セクションで次のディレクティブを使用します。
CPUShare
= value- value は、CPU シェアの数に置き換えます。デフォルト値は 1024 です。数値を増やすと、より多くの CPU 時間がユニットに割り当てられます。
CPUShares
パラメーターの値を設定すると、ユニットファイルでCPUAccounting
が自動的にオンになります。したがって、ユーザーは systemd-cgtop コマンドを使用してプロセッサーの使用状況を監視できます。
CPUShares
パラメーターは、cpu.shares コントロールグループパラメーターを制御します。他の CPU 関連の制御パラメーターを確認するには、コントローラー固有のカーネルドキュメント の cpu
コントローラーの説明を参照してください。
例2.3 ユニットの CPU 消費の制限
デフォルトの 1024 ではなく 1500 の CPU シェアを Apache サービスに割り当てるには、次の内容で新しい
/etc/systemd/system/httpd.service.d/cpu.conf
設定ファイルを作成します。
[Service] CPUShares=1500
変更を適用するには、変更されたサービスファイルが考慮されるように、systemd の設定をリロードして Apache を再起動します。
~]# systemctldaemon-reload
~]# systemctlrestart
httpd.service
CPUQuota
= value- value は、 CPU 時間クォータの値に置き換えて、指定された CPU 時間クォータを実行されるプロセスに割り当てます。パーセンテージで表される
CPUQuota
パラメーターの値は、1 つの CPU で使用可能な合計 CPU 時間に対して、ユニットが最大で取得する CPU 時間を指定します。100% を超える値は、複数の CPU が使用されていることを示します。CPUQuota
は、統合されたコントロールグループ階層の cpu.max 属性と、従来の cpu.cfs_quota_us 属性を制御します。CPUQuota
パラメーターの値を設定すると、ユニットファイルでCPUAccounting
が自動的にオンになります。したがって、ユーザーは systemd-cgtop コマンドを使用してプロセッサーの使用状況を監視できます。
例2.4 CPUQuota の使用
CPUQuota
を 20% に設定すると、実行プロセスに対して、単一の CPU で 20% 以上の CPU 時間が渡されないようにします。
20% の Apache サービス CPU クォータを割り当てるには、次の内容を
/etc/systemd/system/httpd.service.d/cpu.conf
設定ファイルに追加します。
[Service] CPUQuota=20%
変更を適用するには、変更されたサービスファイルが考慮されるように、systemd の設定をリロードして Apache を再起動します。
~]# systemctldaemon-reload
~]# systemctlrestart
httpd.service
メモリーの管理
ユニットのメモリー消費量を制限するには、ユニット設定ファイルの Service セクションで次のディレクティブを使用します。
MemoryLimit
=value- value は、cgroup で実行されるプロセスの最大メモリー使用量の制限に置き換えます。測定単位のキロバイト、メガバイト、ギガバイト、またはテラバイトを指定するには、接尾辞 K、M、Gまたは T を使用します。また、ユニットに対して
MemoryAccounting
パラメーターを有効にする必要があります。
MemoryLimit
パラメーターは、memory.limit_in_bytes コントロールグループパラメーターを制御します。詳細は、コントローラー固有のカーネルドキュメント の メモリー
コントローラーの説明を参照してください。
例2.5 ユニットのメモリー消費の制限
Apache サービスに 1GB のメモリー制限を割り当てるには、
/etc/systemd/system/httpd.service.d/cpu.conf
ユニットファイルの MemoryLimit
設定を変更します。
[Service] MemoryLimit=1G
変更を適用するには、変更されたサービスファイルが考慮されるように、systemd の設定をリロードして Apache を再起動します。
~]# systemctldaemon-reload
~]# systemctlrestart
httpd.service
ブロック IO の管理
ブロック IO を管理するには、ユニット設定ファイルの Service セクションで次のディレクティブを使用します。以下にリストされているディレクティブは、
BlockIOAccounting
パラメーターが有効になっていることを前提としています。
BlockIOWeight
= value- value は、実行されたプロセスの新しい全体的なブロック IO の重みに置き換えます。10 から 1000 の間の単一の値を選択します。デフォルト設定は 1000 です。
BlockIODeviceWeight
=device_name value- value は、device_name で指定されたデバイスのブロック IO の重みに置き換えます。device_name は、名前またはデバイスへのパスに置き換えます。
BlockIOWeight
と同様に、10 から 1000 までの単一の重み値を設定できます。 BlockIOReadBandwidth
=device_name value- このディレクティブを使用すると、ユニットの特定の帯域幅を制限できます。device_name は、デバイスの名前またはブロックデバイスノードへのパスに置き換え、value は帯域幅レートを表します。接尾辞 K、M、G、または T を使用して、測定単位を指定します。接尾辞のない値は、1 秒あたりのバイト数として解釈されます。
BlockIOWriteBandwidth
=device_name value- 指定されたデバイスの書き込み帯域幅を制限します。
BlockIOReadBandwidth
と同じ引数を受け入れます。
前述の各ディレクティブは、対応する cgroup パラメーターを制御します。その他の CPU 関連の制御パラメーターについては、コントローラー固有のカーネルドキュメント の
blkio
コントローラーの説明を参照してください。
注記
現在、
blkio
リソースコントローラーは、バッファーリングされた書き込み操作をサポートしていません。これは主にダイレクト I/O を対象としているため、バッファーリングされた書き込みを使用するサービスは BlockIOWriteBandwidth
で設定された制限を無視します。一方、バッファリングされた読み取り操作はサポートされており、BlockIOReadBandwidth
の制限は、直接読み取りとバッファリングされた読み取りの両方に正しく適用されます。
例2.6 ユニットのブロック IO の制限
/home/jdoe/
ディレクトリーにアクセスする Apache サービスのブロック IO の重みを下げるには、次のテキストを /etc/systemd/system/httpd.service.d/cpu.conf
ユニットファイルに追加します。
[Service] BlockIODeviceWeight=/home/jdoe 750
/var/log/
ディレクトリーからの Apache 読み取りの最大帯域幅を 1 秒あたり 5MB に設定するには、次の構文を使用します。
[Service] BlockIOReadBandwidth=/var/log 5M
変更を適用するには、変更されたサービスファイルが考慮されるように、systemd の設定をリロードして Apache を再起動します。
~]# systemctldaemon-reload
~]# systemctlrestart
httpd.service
その他のシステムリソースの管理
リソース管理を容易にするために、ユニットファイルで使用できるその他のディレクティブがいくつかあります。
DeviceAllow
=device_name options- このオプションは、特定のデバイスノードへのアクセスを制御します。ここで、device_name は
/proc/devices
で指定されているデバイスノードまたはデバイスグループ名へのパスを表します。オプション
をr
、w
、およびm
の組み合わせに置き換えて、ユニットがデバイスノードを読み取り、書き込み、または作成できるようにします。 DevicePolicy
=value- ここで、value は、strict (
DeviceAllow
で明示的に指定されたタイプのアクセスのみを許可する)、closed (/dev/null、/dev/zero、/dev/full、/dev/random などの標準の疑似デバイスへのアクセスを許可する) および/dev/urandom) または auto (デフォルトの動作である明示的なDeviceAllow
が存在しない場合、すべてのデバイスへのアクセスを許可します) のいずれかです。 Slice
=slice_name- slice_name は、ユニットを配置するスライスの名前に置き換えます。デフォルトは system.slice です。スコープユニットは、親スライスに関連付けられているため、この方法で配置することはできません。
ExecStartPost
=command- 現在、
systemd
は cgroup 機能のサブセットのみをサポートしています。ただし、回避策として、ExecStartPost=
オプションをmemory.memsw.limit_in_bytes
パラメーターの設定と共に使用して、サービスのスワップの使用を防ぐことができます。ExecStartPost=
の詳細は、systemd.service (5)
の man ページを参照してください。
例2.7 Cgroup オプションの設定
特定の example サービスのスワップの使用を防ぐために、
memory.memsw.limit_in_bytes
設定をユニットの MemoryLimit
= と同じ値に変更すると想定します。
ExecStartPost=/bin/bash -c "echo 1G > /sys/fs/cgroup/memory/system.slice/example.service/memory.memsw.limit_in_bytes"
変更を適用するには、変更された設定が考慮されるように、
systemd
設定をリロードしてサービスを再起動します。
~]# systemctl daemon-reload ~]# systemctl restart example.service