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

第 9 章 フェアシェアスケジューラ

作業負荷データを分析することによって、特定の作業負荷または作業負荷のグループが CPU 資源を占有しているかどうかを判定できます。作業負荷が CPU 使用量の制限を超えていない場合は、システム上での CPU 時間の割り当て方針を変更することができます。この章で説明するフェアシェアスケジューリングクラスを使用すると、タイムシェアリング (TS) スケジューリングクラスの優先順位方式ではなく、シェア数に基づいて CPU 時間を割り当てることができます。

概要

オペレーティングシステムの基本的な仕事は、どのプロセスがシステム資源へのアクセスを取得できるようにするか調整することです。プロセススケジューラ (別名、ディスパッチャ) は、カーネルの一部であり、プロセスへの CPU の割り当てを制御します。スケジューラには、スケジューリングクラスという概念があります。各スケジューリングクラスでは、クラス内のプロセスのスケジューリングに使用するスケジューリング方針を定義します。TS スケジューラは Solaris オペレーティング環境におけるデフォルトのスケジューラであり、使用可能な CPU へのアクセスをすべてのプロセスに等しく与えます。ただし、特定のプロセスにより多くの資源を与えたい場合もあります。

フェアシェアスケジューラ (FSS) では、各作業負荷に対する使用可能な CPU 資源の割り当てを、その作業負荷の重要性に基づいて制御します。この重要性は、各作業負荷に割り当てる CPU 資源のシェア数で表します。

各プロジェクトに CPU シェアを与えて、CPU 資源に対するプロジェクトの使用権を制御します。FSS では、プロジェクトに属するプロセス数ではなく、割り当てられたシェア数に基づいて、プロジェクト間に CPU 資源が公平に配分されることが保証されています。FSS は、他のプロジェクトとの比較に基づいて、CPU 資源を多く使用するプロジェクトの CPU 使用権を減らし、CPU 資源の使用が少ないプロジェクトの CPU 使用権を増やすことで公平さを実現します。

FSS は、カーネルスケジューリングクラスモジュールとクラスに固有な dispadmin(1M) および priocntl(1) コマンドから構成されます。FSS が使用するプロジェクトシェアは、project データベース内の project.cpu-shares プロパティで指定します。

CPU シェアの定義

「シェア」という用語は、プロジェクトに割り当てられる CPU 資源の配分を定義するために使用されます。プロジェクトに割り当てる CPU シェア数を他のプロジェクトよりも多くすると、そのプロジェクトがフェアシェアスケジューラから受け取る CPU 資源も多くなります。

CPU シェアは、CPU 資源の比率ではありません。シェアは、他の作業負荷との比較に基づいた作業負荷の相対的な重要性を定義します。プロジェクトに CPU シェアを割り当てる場合に重要なことは、プロジェクトが持つシェア数自体ではありません。他のプロジェクトと比較して、そのプロジェクトがシェアをいくつ持っているかを把握することが重要です。 また、そのプロジェクトが CPU 資源について、他のいくつのプロジェクトと競合しているかということも考慮に入れる必要があります。


注 -

シェア数がゼロのプロジェクトに属するプロセスは、常に最下位のシステム優先順位 (0) で実行されます。このようなプロセスが実行されるのは、シェア数がゼロでないプロジェクトが CPU 資源を使用していないときだけです。


CPU シェアとプロセスの状態

Solaris オペレーティング環境では、プロジェクトの作業負荷は一般に複数のプロセスから構成されます。フェアシェアスケジューラの観点からは、各プロジェクトの作業負荷は、アイドル状態かアクティブ状態のどちらかです。プロジェクトのどのプロセスも CPU 資源を使用していないとき、プロジェクトはアイドル状態であるといいます。 このような場合、プロセスは一般にスリープ (入出力の完了を待機している状態) または停止状態にあります。プロジェクトの 1 つ以上のプロセスが CPU 資源を使用しているとき、プロジェクトはアクティブ状態であるといいます。 すべてのアクティブなプロジェクトが持つシェア数の合計が、プロジェクトに割り当てられる CPU 資源の配分の計算に使用されます。

次の式から、FSS スケジューラによるプロジェクトごとの CPU 資源の割り当て方法が算出されます。(allocation = 割り当て、project = プロジェクト、share = シェア)

図 9-1 FSS スケジューラのシェア計算

FSS スケジューラのシェアを表す方程式。

アクティブなプロジェクトが増えると、各プロジェクトの CPU 割り当ては減りますが、プロジェクト間の CPU 割り当て比率は変わりません。

CPU シェアと使用率

シェア割り当ては、使用率とは異なります。CPU 資源の 50% が割り当てられているプロジェクトの CPU 使用率は、平均するとわずか 20% ほどです。その上、シェアが CPU 使用量を制限するのは、他のプロジェクトと競合するときだけです。プロジェクトに対する割り当てが低い場合でも、そのプロジェクトがシステムで単独に実行されているときは、常に 100% の処理能力を CPU から受け取ります。使用可能な CPU サイクルが浪費されることはありません。つまり、使用可能な CPU サイクルはプロジェクト間に配分されます。

動作中の作業負荷に小さいシェアを割り当てると、パフォーマンスが低下します。ただし、システムが過負荷にならないかぎり、シェア割り当て数が原因で作業が完了しないことはありません。

CPU シェアの例

2 つの CPU を搭載したシステムがあり、それらの CPU は CPU にバインドされた 2 つの作業負荷 A および B を並列に実行しているとします。各作業負荷は別個のプロジェクトとして実行されています。各プロジェクトは、プロジェクト ASA シェアが割り当てられ、プロジェクト BSB シェアが割り当てられるように構成されています。

従来の TS スケジューラを使用した場合、システムで実行されている各作業負荷には、平均して同じ量の CPU 資源が与えられます。つまり、各作業負荷にはシステム容量の 50% が割り当てられます。

FSS スケジューラの制御で実行する場合でも、SA = SB のシェアを割り当てると、各プロジェクトにほぼ等量の CPU 資源が与えられます。これに対して、プロジェクトに異なるシェア数を与えた場合、CPU 資源の割り当て量は異なります。

次に示す 3 つの例は、さまざまな構成でのシェアの働きを示しています。これらの例に示されているとおり、シェア数は、要求が使用可能な資源量と同じまたはそれを超えている場合にのみ使用量を数学的に正確に表します。

例 1: CPU にバインドされた 2 つのプロセスが各プロジェクトに存在する場合

プロジェクト A および B がそれぞれ CPU にバインドされたプロセスを 2 つ持ち、かつ SA = 1 および SB = 3 である場合、シェアの合計数は 1 + 3 = 4 になります。 この構成で、十分な数の CPU 要求があると、プロジェクト A および B には、それぞれ CPU 資源の 25% と 75% が割り当てられます。

図。

例 2: プロジェクト間に競合がない場合

プロジェクト A および B がそれぞれ CPU にバインドされたプロセスを 1 つだけ持ち、かつ SA = 1 および SB = 100 である場合、シェアの合計数は 101 になります。 各プロジェクトは、実行中のプロセスを 1 つしか持たないため、CPU を 1 つしか使用できません。この構成では、CPU 資源を得るための競合がプロジェクト間に存在しないので、プロジェクト A および B には、それぞれ全 CPU 資源の 50% が割り当てられます。この構成の場合、CPU シェア数は CPU 資源の割り当てに影響しません。プロジェクトへの割り当ては同じ (50/50) になります。これは、両方のプロジェクトに割り当てられるシェア数がゼロの場合でも同様です。

図。

例 3: 一方のプロジェクトが実行されない場合

プロジェクト A および B がそれぞれ CPU にバインドされたプロセスを 2 つ持ち、かつ A に 1 シェア、B に 0 シェアが与えられている場合、プロジェクト B には CPU 資源が割り当てられず、プロジェクト A にすべての CPU 資源が割り当てられます。プロジェクト B のプロセスは常にシステム優先順位 0 で実行されるため、実行される可能性はまったくありません。これは、プロジェクト A のプロセスの方が常に高い優先順位を持っているためです。

図。

FSS の構成

プロジェクトとユーザー

プロジェクトは、FSS スケジューラの作業負荷コンテナです。プロジェクトに割り当てられているユーザーのグループは、個別の管理可能なブロックとして扱われます。個人ユーザー用に独自のシェア数を持つプロジェクトを作成できます。

ユーザーは、異なるシェア数が割り当てられているさまざまなプロジェクトのメンバーになることができます。プロセスをあるプロジェクトから別のプロジェクトに移動すると、プロセスに割り当てられる CPU 資源量は変化します。

project データベースとネームサービスについては、project データベース」を参照してください。

CPU シェアの構成

CPU シェアの構成は project データベースのプロパティとして、ネームサービスによって管理されます。

プロジェクトに関連付けられている最初のタスクまたはプロセスが setproject(3PROJECT) ライブラリ関数を使って生成されると、project データベース内で資源制御 project.cpu-shares として定義されている CPU シェア数がカーネルに渡されます。資源制御 project.cpu-shares が定義されていないプロジェクトには、1 シェアが割り当てられます。

次の例では、/etc/project ファイル内のエントリでプロジェクト x-files のシェア数に 5 が設定されています。


x-files:100::::project.cpu-shares=(privileged,5,none)

プロジェクトに割り当てられている CPU シェア数を、プロセスの実行中にデータベースで変更しても、プロジェクトのシェア数は、その時点では変更されません。 変更内容を有効にするには、プロジェクトを再起動する必要があります。

プロジェクトに割り当てられているシェア数を、project データベース内のプロジェクトの属性を変更しないで一時的に変更するには、prctl(1) を使用します。たとえば、x-files プロジェクトに関連付けられているプロセスの実行中に、そのプロジェクトの資源制御 project.cpu-shares の値を 3 に変更するには、次のように入力します。


# prctl -r -n project.cpu-shares -v 3 -i project x-files

-r

指定された資源制御の現在の値を置き換えます。

-n name

資源制御の名前を指定します。

-v val

資源制御の値を指定します。

-i idtype

ID タイプを指定します。

x-files

変更対象を指定します。この例では、プロジェクト x-files が変更対象です。

プロジェクト ID 0 のプロジェクト system には、起動時の初期化スクリプトで起動されるすべてのシステムデーモンが含まれます。system は、無制限のシェア数を持つプロジェクトとしてみなされます。したがって、プロジェクト system は、他のプロジェクトに与えられているシェア数とは関係なく、常に最初にスケジュールされます。プロジェクト system に無制限のシェア数を割り当てない場合は、project データベースでこのプロジェクトのシェア数を変更します。

前述のように、シェア数がゼロのプロジェクトに属するプロセスには、常にシステム優先順位 0 が与えられます。シェア数が 1 以上のプロジェクトは、優先順位 1 以上で実行されます。したがって、シェア数がゼロのプロジェクトは、ゼロ以外のシェア数を持つプロジェクトが CPU 資源を要求していないときにだけスケジュールされます。

1 つのプロジェクトに割り当てられるシェアの最大数は 65535 です。

FSS とプロセッサセット

FSS は、プロセッサセットと連携して使用すると、連携させない場合よりも、各プロセッサセット上で実行するプロジェクト間の CPU 資源の割り当てをよりきめ細かく制御できます。FSS スケジューラは、プロセッサセットを完全に独立したパーティションとして処理します。つまり、各プロセッサセットは、CPU 割り当てについてそれぞれ個別に制御されます。

1 つのプロセッサセットで実行されるプロジェクトの CPU 割り当てが、別のプロセッサセットで実行されるプロジェクトの CPU シェアや動作によって影響を受けることはありません。なぜなら、異なるプロセッサセットで実行されるプロジェクトが同じ資源について競合することはないからです。競合が発生するのは、プロジェクトが同じプロセッサセット内で実行されている場合だけです。

プロジェクトに割り当てられているシェア数はシステム全体に適用されます。どのプロセッサセットで実行されようと、プロジェクトの各部分には同じシェア数が与えられます。

次に示すように、プロセッサセットが使用されている場合、プロジェクトの CPU 割り当ては、各プロセッサセット内で実行されるアクティブなプロジェクトに対して算出されます。(allocation = 割り当て、project = プロジェクト、share = シェア、processor set = プロセッサセット)

図 9-2 プロセッサセットを使用する場合の FSS スケジューラのシェア計算

この方程式は、プロセッサセット内で実行されている各プロジェクトに対する CPU 割り当てを FSS スケジューラが算出する方法を示しています。

異なるプロセッサセット内で実行されるプロジェクトのパーティションは、異なる CPU 割り当てを持つことになります。1 つのプロセッサセット内の各プロジェクトパーティションに対する CPU 割り当ては、同じプロセッサセット内で実行される他のプロジェクトの割り当てにだけ依存します。

プロセッサセット境界内で実行されるアプリケーションのパフォーマンスと可用性が、新しいプロセッサセットの導入によって影響を受けることはありません。また、他のプロセッサセットで実行されるプロジェクトのシェア割り当ての変更によって、アプリケーションが影響を受けることもありません。

空のプロセッサセット (プロセッサが存在しないセット) や、プロセッサセットにバインドされたプロセスを持たないプロセッサセットは、FSS スケジューラの動作にまったく影響を与えません。

FSS とプロセッサセットの例

8 つの CPU を持つサーバーがプロジェクト AB、および C 内で CPU にバインドされたアプリケーションをいくつか実行しているものとします。プロジェクト A には 1 シェア、プロジェクト B には 2 シェア、プロジェクト C には 3 シェアがそれぞれ割り当てられています。

プロジェクト A は、プロセッサセット 1 だけで実行されています。 プロジェクト B は、プロセッサセット 1 および 2 で実行されています。 プロジェクト C は、プロセッサセット 1、2、および 3 で実行されています。各プロジェクトには、使用可能なすべての CPU 処理能力を利用するだけの十分な数のプロセスが存在しているものとします。したがって、CPU 資源を得るための競合が各プロセッサセットで常に発生します。

この図は、3 つのプロジェクト内で CPU にバインドされたアプリケーションを実行する場合、サーバーの 8 つの CPU がどのように割り当てられるかを示します。

このようなシステムでは、システム全体でのプロジェクトの CPU 割り当ての合計は、次のようになります。(pset = プロセッサセット)

プロジェクト A 

4% = (1/6 * 2/8) pset1

プロジェクト B 

28% = (2/6 * 2/8) pset1+ (2/5 * 4/8)pset2

プロジェクト C 

67% = (3/6 * 2/8) pset1+ (3/5 * 4/8)pset2+ (3/3 * 2/8) pset3

これらの割合は、プロジェクトに与えられている CPU シェア値とは一致しません。ただし、各プロセッサセット内では、プロジェクトごとの CPU 割り当て比率はプロジェクトのそれぞれのシェアに比例します。

このシステム上にプロセッサセットが存在しない場合、CPU 資源の配分は、次に示すように、異なったものになります。

プロジェクト A 

16.66% = (1/6) 

プロジェクト B 

33.33% = (2/6) 

プロジェクト C 

50% = (3/6) 

FSS と他のスケジューリングクラスの併用

デフォルトでは、FSS スケジューリングクラスは、タイムシェアリング (TS)、対話型 (IA)、および固定優先順位 (FX) の各スケジューリングクラスと同じ範囲の優先順位 (0 から 59) を使用します。そのため、これらのスケジューリングクラスのプロセスが同じプロセッサセットを共有しないようにする必要があります。FSS、TS、IA、および FX の各クラスにプロセスが混在すると、予期せぬスケジューリング処理が実行される場合があります。

プロセッサセットを使用する場合は、1 つのシステム内で TS、IA、および FX を FSS と混在させることができます。ただし、各プロセッサセットで実行されるすべてのプロセスは、1 つのスケジューリングクラスに所属している必要があります。このようにすると、これらのプロセスが同じ CPU について競合することはありません。プロセッサセットを使用しない場合は、特に FX スケジューラを FSS スケジューリングクラスと併用しないようにしてください。これにより、FX クラスのアプリケーションが高い優先順位を使用して、FSS クラスのアプリケーションの実行を妨げることはありません。

TS クラスと IA クラスのプロセスは、同じプロセッサセット内で、またはプロセッサセットが存在しない同じシステム内で混在させることができます。

Solaris オペレーティング環境では、スーパーユーザー権限を持つユーザーは、リアルタイム (RT) スケジューラも利用できます。デフォルトでは、RT スケジューリングクラスは FSS とは異なる範囲のシステム優先順位 (通常は 100 から 159) を使用します。 RT と FSS は互いに重複しない範囲の優先順位を使用しているので、FSS は同じプロセッサセット内の RT スケジューリングクラスと共存できます。ただし、FSS スケジューリングクラスは、RT クラスで実行するプロセスを制御することはできません。

たとえば、4 つのプロセッサから構成されるシステムで、CPU に結合されているシングルスレッドの RT プロセスは 1 つのプロセッサを占有できます。システムが FSS も実行している場合、通常のユーザープロセスは、RT プロセスが使用していない残りの 3 つの CPU について競合します。RT プロセスは CPU を使い続けることはありません。 RT プロセスがアイドル状態になったとき、FSS は 4 つのプロセッサをすべて使用します。

次のコマンドを入力して、プロセッサセットが実行しているスケジューリングクラスを特定し、各プロセッサセットが TS、IA、FX、または FSS のプロセスのいずれかを実行するように構成されていることを確認します。


$ ps -ef -o pset,class | grep -v CLS | sort | uniq
1 FSS
1 SYS
2 TS
2 RT
3 FX

システムにデフォルトのスケジューラを設定するには、「FSS の構成例」dispadmin(1M) を参照してください。実行中のプロセスを別のスケジューリングクラスに移動するには、「FSS の構成例」priocntl(1) を参照してください。

FSS の監視

prstat(1M) を使用して、CPU 使用量をアクティブなプロジェクトごとに監視できます。

タスク用の拡張アカウンティングデータを使用して、長期間使用される CPU 資源の合計量について、プロジェクトごとの統計情報を取得できます。詳細は、第 7 章「拡張アカウンティング」を参照してください。

システムの CPU 使用量をプロジェクトごとに監視する方法

システム上で実行されるプロジェクトの CPU 使用量を監視するには、次のように入力します。


% prstat -J

プロセッサセット内の CPU 使用量をプロジェクトごとに監視する方法

プロセッサセットに登録されているプロジェクトの CPU 使用量を監視するには、次のように入力します。


% prstat -J -C pset-list
pset-list

コンマ区切りのプロセッサセット ID のリスト

FSS の構成例

Solaris 環境における他のスケジューリングクラスと同様に、FSS では、スケジューリングクラスを設定するコマンドや、スケジューラのチューンアップパラメータを設定するコマンド、個々のプロセスのプロパティを設定するコマンドを使用できます。

スケジューリングクラスの設定方法

dispadmin コマンドを使用して、システムのデフォルトのスケジューラとして FSS を設定します。


# dispadmin -d FSS

この変更指定は次の再起動で有効になります。再起動後は、システムのすべてのプロセスが FSS スケジューリングクラスで実行されます。

プロセスを TS から FSS クラスに手動で移動する方法

デフォルトのスケジューリングクラスを変更した後で再起動しなくても、プロセスを TS スケジューリングクラスから FSS スケジューリングクラスに手動で移動できます。

  1. スーパーユーザーになります。

  2. init プロセス (pid 1) を FSS スケジューリングクラスに移動します。


    # priocntl -s -c FSS -i pid 1
    
  3. すべてのプロセスを TS スケジューリングクラスから FSS スケジューリングクラスに移動します。


    # priocntl -s -c FSS -i class TS
    

すべてのプロセスは、再起動後には再び TS スケジューリングクラスで実行されます。

プロセスをすべてのユーザークラスから FSS クラスに手動で移動する方法

TS 以外のデフォルトのクラスを使用している場合、たとえば、デフォルトで IA クラスを使用するウィンドウ環境がシステムで実行されている場合があります。デフォルトのスケジューリングクラスを変更した後で再起動しなくても、すべてのプロセスを FSS スケジューリングクラスに手動で移動できます。

  1. スーパーユーザーになります。

  2. init プロセス (pid 1) を FSS スケジューリングクラスに移動します。


    # priocntl -s -c FSS -i pid 1
    
  3. すべてのプロセスを現在のスケジューリングクラスから FSS スケジューリングクラスに移動します。


    # priocntl -s -c FSS -i all
    

すべてのプロセスは、再起動後には再びデフォルトのスケジューリングクラスで実行されます。

プロジェクトのプロセスを FSS クラスに移動する方法

特定のプロジェクト内のプロセスを現在のスケジューリングクラスから FSS スケジューリングクラスに手動で移動できます。

  1. スーパーユーザーになります。

  2. プロジェクト ID 10 で実行するプロセスを FSS スケジューリングクラスに移動します。


# priocntl -s -c FSS -i projid 10

プロジェクトのプロセスは、再起動後には再びデフォルトのスケジューリングクラスで実行されます。

スケジューラのパラメータを調整する方法

dispadmin コマンドを使用して、FSS スケジューラのタイムクォンタム (time quantum) 値を調べ、調整できます。タイムクォンタムとは、スレッドがプロセッサに上で実行を開始してからそのプロセッサを放棄するまでの時間量のことです。FSS スケジューラの現在のタイムクォンタムを表示するには、次のように入力します。


$ dispadmin -c FSS -g
#
# Fair Share Scheduler Configuration
#
RES=1000
#
# Time Quantum
#
QUANTUM=110

-g オプションを使用するときに、同時に -r オプションも指定すると、タイムクォンタム値の表示に使用する最小単位を指定できます。最小単位を指定しないと、タイムクォンタム値はデフォルトのミリ秒で表示されます。次のコマンドを入力します。


$ dispadmin -c FSS -g -r 100
#
# Fair Share Scheduler Configuration
#
RES=100
#
# Time Quantum
#
QUANTUM=11

FSS スケジューリングクラスにスケジューリングパラメータを設定するには、dispadmin -s を使用します。file 内の値は、-g オプションで得られる出力と同じ形式で指定する必要があります。これらの値は、カーネル内の現在の値を上書きします。次のコマンドを入力します。


$ dispadmin -c FSS -s file

関連項目

FSS スケジューラの使用方法については、priocntl(1)ps(1)dispadmin(1M)、および FSS(7) を参照してください。