Solaris のシステム管理 (資源管理とネットワークサービス)

第 8 章 資源制御

第 7 章「拡張アカウンティング」で説明したようにシステム上の作業負荷の資源消費を判定したら、資源の使用方法に制限を設けることができます。制限を設けると、作業負荷による資源の過剰消費を防ぐことができます。資源制御は、UNIX の資源制限の概念を拡張した機能で、資源を制限するために使用される制約メカニズムです。

概要

従来から、UNIX システムには資源制限機能があります (rlimit)。rlimit の機能を使用すると、管理者は、プロセスが使用できる資源の量に対して 1 つ以上の数値制限を設定できます。この制限には、プロセスごとの CPU 使用時間、プロセスごとのコアファイルサイズ、プロセスごとの最大ヒープサイズが含まれます。ヒープサイズは、プロセスのデータセグメントに割り当てられるメモリー領域のサイズです。

Solaris オペレーティング環境では、プロセスごとの資源制限という概念が、第 6 章「プロジェクトとタスク」で説明したタスクおよびプロジェクトに拡張されています。この拡張された資源制限機能は、システム全体に適用できます。この拡張機能は、「資源制御」(rctls) 機能によって提供されます。

資源制御機能は、資源制限機能に対する互換インタフェースを提供します。資源制限機能を使用する既存のアプリケーションは、変更せずに、引き続き使用できます。また、既存のアプリケーションは、資源制御機能を利用するように変更されたアプリケーションと同様に監視することができます。

資源制御機能は、システム資源に対する制約メカニズムを提供します。これにより、プロセス、タスク、およびプロジェクトが、指定したシステム資源を過剰消費することを防止できます。このメカニズムは、資源の過剰消費を防ぐことにより、より管理しやすいシステムを実現します。

制約メカニズムは、容量計画を実施するときにも使用できます。制約を設けることにより、アプリケーションへの資源の提供を必ずしも拒否することなく、アプリケーションが必要とする資源量に関する情報を取得できます。

また、資源制御は、資源管理機能のための簡単な属性メカニズムとしても利用できます。たとえば、フェアシェアスケジューラ (FSS) のスケジューリングクラスで動作しているプロジェクトで利用できる CPU のシェア数は、資源制御 project.cpu-shares によって定義されます。プロジェクトは資源制御によって一定のシェア数を割り当てられるため、制御の超過につながる各種のアクションは許可されません。そのため、資源制御 project.cpu-shares の現在値は、指定したプロジェクトの属性とみなすことができます。

資源制御の管理

資源制御機能は、project データベース (第 6 章「プロジェクトとタスク」参照) によって構成されます。資源制御の属性は、project データベースエントリの最後のフィールドで設定します。各資源制御に対応付けられる値は、括弧で囲まれ、コンマ区切りのプレーンテキストとして示されます。 括弧内の値は「action 文節」を示します。各 action 文節は、特権レベル、しきい値、および特定のしきい値に対応付けられたアクションで構成されます。各資源制御は複数の action 文節を持つことができ、各 action 文節もコンマで区切られます。次のエントリは、プロジェクトエンティティにおけるプロセスごとのアドレス空間制限と、タスクごとの軽量プロセス (LWP) 制限を定義します。


development:101:Developers:::task.max-lwps=(privileged,10,deny);
  process.max-address-space=(privileged,209715200,deny)

rctladm(1M) コマンドを使用すると、資源制御機能の実行時に問い合わせや制御機能の変更を広域的に行うことができます。 prctl(1) コマンドを使用すると、資源制御機能の実行時に問い合わせや制御機能の変更をローカルに行うことができます。

使用可能な資源制御

次の表に、このリリースで使用できる標準の資源制御を示します。

この表では、各制御によって制約される資源について説明し、project データベースにおけるその資源のデフォルトの単位を示します。デフォルトの単位には次の 2 種類があります。

したがって、project.cpu-shares は、プロジェクトで使用することが許可されているシェア数を示します。 一方、process.max-file-descriptor は、open(2) システムコールによってプロセスに割り当てられるファイルの最大数を示します。

表 8–1 標準の資源制御

制御名 

説明 

デフォルトの単位 

project.cpu-shares

プロジェクトに対して、FSS(7) で使用することが許可されている CPU シェア数

数量 (シェア数) 

task.max-cpu-time

タスクのプロセスで使用できる最大 CPU 時間 

時間 (秒) 

task.max-lwps

タスクのプロセスで同時に使用できる LWP の最大数 

数量 (LWP 数) 

process.max-cpu-time

プロセスで使用できる最大の CPU 時間 

時間 (秒) 

process.max-file-descriptor

プロセスで使用できる最大のファイル記述子インデックス 

インデックス (最大ファイル記述子) 

process.max-file-size

プロセスで書き込むことができるファイルオフセットの最大サイズ 

サイズ (バイト) 

process.max-core-size

プロセスによって作成されるコアファイルの最大サイズ 

サイズ (バイト) 

process.max-data-size

プロセスで使用できるヒープメモリーの最大サイズ 

サイズ (バイト) 

process.max-stack-size

プロセスで使用できるスタックメモリーセグメントの最大サイズ 

サイズ (バイト) 

process.max-address-space

プロセスで使用できる、セグメントサイズの総計としての最大アドレス空間 

サイズ (バイト) 

資源制御値と特権レベル

資源制御のしきい値は、ローカルアクションやロギングなどの広域アクションをトリガーできる実行ポイントを設定します。

各しきい値は、次の 3 種類の特権レベルのいずれかに対応付ける必要があります。

資源制御は、システムまたは資源の提供者によって定義されるシステム値を 1 つ持つことが保証されます。システム値は、オペレーティングシステムが提供できる資源の量を意味します。

特権値はいくつでも定義できます。基本値は 1 つだけ許可されます。特権値を指定しないで実行される操作には、デフォルトで、基本レベルの特権が割り当てられます。

資源制御値の特権レベルは、資源制御ブロックの特権フィールドで、RCTL_BASIC、RCTL_PRIVILEGED、または RCTL_SYSTEM のように定義します。詳細は、getrctl(2) を参照してください。prctl コマンドを使用すると、基本レベルおよび特権レベルに対応付けられている値を変更できます。

資源制御値に対応付けられたアクション

資源制御に設定された各しきい値に対して、1 つ以上のアクションを対応付けることができます。

実装上の制限により、しきい値に設定できるアクションは、各制御のグローバルプロパティによって制限されます。次の表に、使用できるシグナルアクションを示します。シグナルの詳細については、signal(3HEAD) を参照してください。

表 8–2 資源制御値に使用できるシグナル

シグナル 

注 

SIGABRT 

 

SIGHUP 

 

SIGTERM 

 

SIGKILL 

 

SIGSTOP 

 

SIGXRES 

 

SIGXFSZ 

RCTL_GLOBAL_FILE_SIZE プロパティ (process.max-file-size) を持つ資源制御だけで使用可能。詳細は rctlblk_set_value(3C) を参照

SIGXCPU 

RCTL_GLOBAL_CPUTIME プロパティ (process.max-cpu-time) を持つ資源制御だけで使用可能。詳細は rctlblk_set_value(3C) を参照

資源制御のフラグとプロパティ

システム上の資源制御には、それぞれ特定のプロパティセットが対応付けられています。このプロパティセットは、一連のグローバルフラグとして定義されます。グローバルフラグは、その資源が制御されているすべてのインスタンスに対応付けられます。グローバルフラグは変更できませんが、rctladm または getrctl システムコールを使って取得できます。

ローカルフラグは、特定のプロセスまたはプロセス集合に対する資源制御の特定のしきい値について、デフォルトの動作と構成を定義します。あるしきい値のローカルフラグが、同じ資源制御で定義されている別のしきい値の動作に影響することはありません。ただし、グローバルフラグは、特定の制御に対応付けられているすべての値の動作に影響します。ローカルフラグは、対応するグローバルフラグによる制約の範囲内で、prctl コマンドまたは setrctl システムコールを使って変更できます (setrctl(2) 参照)。

ローカルフラグ、グローバルフラグ、およびそれらの定義の詳細なリストについては、rctlblk_set_value(3C) を参照してください。

特定の資源制御がしきい値に達したときのシステムの動作を確認するには、rctladm を使ってその資源制御のグローバルフラグを表示します。たとえば、process.max-cpu-time の値を表示するには、次のように入力します。


$ rctladm process.max-cpu-time
	process.max-cpu-time   syslog=off   [ lowerable no-deny cpu-time inf ]

広域フラグは、次のことを示します。

lowerable

この制御の特権値を下げるのに、スーパーユーザー特権を必要としない

no-deny

しきい値を超えても、資源へのアクセスは拒否されない

cpu-time

資源がしきい値に達したとき、SIGXCPU を送信できる

inf

RCTL_LOCAL_MAXIMAL が設定されている値は、実際には無限数を意味し、制約はない

資源制御のローカル値とアクションを表示するには、prctl を使用します。


$ prctl -n process.max-cpu-time $$
	353939: -ksh
	process.max-cpu-time   [ lowerable no-deny cpu-time inf ]
		18446744073709551615 privileged signal=XCPU   [ max ]
		18446744073709551615 system     deny          [ max ]

この例では、2 つのしきい値の両方に max (RCTL_LOCAL_MAXIMAL) フラグが設定されており、資源制御には inf (RCTL_GLOBAL_INFINITE) フラグが設定されています。したがって、設定されているように、両方のしきい値は無限値を意味し、これらの値を上回ることはありません。

資源制御の実行

1 つの資源には、複数の資源制御を設定できます。 資源制御は、プロセスモデルの包含レベルごとに 1 つずつ設定できます。 同じ資源上の異なるコンテナレベルで資源制御がアクティブな場合、まず、最も小さいコンテナの制御が実行されます。したがって、process.max-cpu-timetask.max-cpu-time の両方の制御が同時に検出された場合は、まず process.max-cpu-time に対するアクションが実行されます。

図 8–1 プロセス集合、コンテナの包含関係、およびその資源制御セット

この図では、包含レベルごとに資源制御が設定されています。

資源制御イベントの広域監視

プロセスの資源消費が不明な場合がよくあります。 資源消費に関する情報を入手するには、rctladm(1M) で利用できる広域資源制御アクションを使用します。 rctladm を使用して、資源制御に syslog アクションを設定します。 その資源制御が管理するエンティティでしきい値が検出されると、設定したログレベルでシステムメッセージが記録されます。

構成

表 8–1 に示されている各資源制御をプロジェクトに割り当てることができるのは、ログイン時、newtask(1) が呼び出されたとき、または at(1)batch (at(1) を参照)、cron(1M) など、プロジェクトを扱うことができる起動ツールが呼び出されたときです。開始される各コマンドは、呼び出し側のユーザーのデフォルトプロジェクトとは異なるタスクで起動されます。

project データベース内のエントリに対する更新は、/etc/project ファイルまたはネットワークネームサービスのデータベース表現のどちらに対するものであっても、現在アクティブなプロジェクトには適用されません。 更新内容は、新しいタスクが login(1) または newtask によってプロジェクトに参加したときに適用されます。

動作中のシステム上の資源制御値を一時的に更新する

project データベースで変更された値は、プロジェクト内で開始される新しいタスクに対してだけ有効になります。ただし、rctladm および prctl コマンドを使用すると、動作中のシステムの資源制御を更新できます。

ログ状態の更新

rctladm コマンドは、システム全体で、各資源制御の広域ログ状態に影響を与えます。このコマンドは、広域的状態を表示し、制御の限度を超えたときに syslog が記録するログのレベルを設定できます。

資源制御の更新

prctl コマンドを使用すると、プロセスごと、タスクごと、またはプロジェクトごとに資源制御値とアクションを表示したり、一時的に変更したりできます。プロジェクト ID、タスク ID、またはプロセス ID を入力として指定すると、このコマンドは、定義されているレベルで資源制御に対して動作します。

変更した値とアクションはすぐに適用されます。ただし、これらの変更が適用されるのは、現在のセッションだけです。変更内容は、project データベースには記録されません。システムを再起動すると、変更内容は失われます。資源制御を永続的に変更するには、project データベースで変更を行う必要があります。

project データベースで変更できる資源制御設定はすべて、prctl コマンドを使って変更することもできます。基本値と特権値はどちらも、追加、削除が可能で、またアクションも変更できます。デフォルトでは、基本レベルの資源制御はすべての操作の影響を受けます。スーパーユーザー特権があるプロセスとユーザーは、特権レベルの資源制御も変更できます。システム資源の制御は変更できません。

資源制御の使用

プロジェクト内の各タスクの最大 LWP 数を設定する方法

/etc/project データベースで次のエントリを入力し、x-files プロジェクトの各タスクの最大 LWP 数を 3 に設定します。


x-files:100::root::task.max-lwps=(privileged,3,deny)

プロジェクト x-filesnewtask と結合することによって新しいタスクを作成したスーパーユーザーは、そのタスクの実行中、LWP を 3 つまでしか作成できません。次の注釈付きのセッション例を参照してください。


# newtask -p x-files csh

# prctl -n task.max-lwps $$
688: csh
task.max-lwps
                            3 privileged deny
                   2147483647 system     deny
# id -p
uid=0(root) gid=1(other) projid=100(x-files)

# ps -o project,taskid -p $$
 PROJECT TASKID
 x-files   236

# csh        /* 2 つ目の LWP を作成 */

# csh        /* 3 つ目の LWP を作成 */

# csh        /* これ以上 LWP を作成することはできない */
Vfork failed

#

プロジェクトに複数の制御を設定する方法

/etc/project ファイルには、各プロジェクトごとに複数の資源制御設定を記述でき、さらに各資源制御ごとに複数のしきい値を記述できます。しきい値は action 文節で定義されます。複数の値はコンマで区切られます。

ファイル内の次の行は、basic (基本) レベルの制御を設定します。この設定では、x-files プロジェクトのタスクごとの最大 LWP 数に対して、アクションは発生しません。また、タスクごとの最大 LWP 数に対して特権レベルの deny 制御を設定しています。この制御により、前述の例のように、最大数を超える数の LWP を作成しようとすると失敗します。最後に、プロセスごとの最大ファイル記述子は basic レベルに制限されており、最大値を超えるオープンコールは失敗します。


x-files:101::root::task.max-lwps=(basic,10,none),(privileged,500,deny);
    process.max-file-descriptor=(basic,128,deny)

prctl を使用する方法

スーパーユーザーは、prctl と入力することにより、実行中の現在のシェルの最大ファイル記述子を表示できます。


# prctl -n process.max-file-descriptor $$
8437:   sh
process.max-file-descriptor              [ lowerable deny ]
                          256 basic      deny
                        65536 privileged deny
                   2147483647 system     deny

prctl コマンドを使って新しい特権値を一時的に追加し、x-files プロジェクトの各タスクで 4 つ以上の LWP の使用を拒否することもできます。結果は プロジェクト内の各タスクの最大 LWP 数を設定する方法の結果と同じです。次の注釈付きサンプルセッションでこれを示します。


# newtask -p x-files

# id -p
uid=0(root) gid=1(other) projid=101(x-files)

# prctl -n task.max-lwps -t privileged -v 3 -e deny -i project x-files

# prctl -n task.max-lwps -i project x-files
670:    sh
task.max-lwps
                            3 privileged deny
                   2147483647 system     deny

prctl -r を使って資源制御の最小値を変更することもできます。


# prctl -n process.max-file-descriptor -r -v 128 $$

rctladm を使用する方法

rctladm を使用すると、資源制御のグローバル syslog 属性を有効にできます。制御が限界を超えたとき、指定された syslog レベルで通知が記録されます。次のコマンドを入力します。


# rctladm -e syslog process.max-file-descriptor

容量に関する警告

資源制御に対してグローバルアクションを設定すると、資源制御値を超えたエンティティに関する通知を受け取ることができます。

たとえば、一般的な作業負荷のための十分な CPU 資源が Web サーバーに割り当てられているかどうかを確認する場合を考えます。この容量は、sar(1) データで CPU のアイドル時間と平均負荷率を分析すれば判定できます。 また、拡張アカウンティングデータを調べて、Web サーバープロセスで同時に実行しているプロセス数を確認することもできます。

より簡単な方法は、Web サーバーをタスクに配置することです。その上で、syslog を使ってグローバルアクションを設定すると、タスクがマシンのパフォーマンスに適した LWP の計画数を上回ったときに、警告が通知されます。

Web サーバーに十分な CPU 容量が割り当てられているかどうかを判定する方法

  1. prctl コマンドを使用して、httpd プロセスを含むタスクにスーパーユーザーが所有する特権レベルの資源制御を設定します。各タスクの LWP の総数を 40 に制限し、すべてのローカルアクションを無効にします。


    # prctl -n task.max-lwps -v 40 -t privileged -d all `pgrep httpd`
    
  2. 資源制御 task.max-lwps で、システムログのグローバルアクションを有効にします。


    # rctladm -e syslog task.max-lwps
    
  3. 作業負荷が資源制御を超えるかどうかを監視します。

    作業負荷が資源制御を超えると、次のような内容が /var/adm/messages に記録されます。


    Jan  8 10:15:15 testmachine unix: [ID 859581 kern.notice] 
    NOTICE: privileged rctl task.max-lwps exceeded by task 19