この章では、N1 Grid Engine 6.1 ソフトウェアのリソース割り当て機能を使用して、ユーザー、プロジェクト、ホスト、クラスタキュー、並列環境別にリソースを制限する方法を説明します。こうした制限は、ユーザーアクセスリスト、部署、ホストグループを使用して表すことができます。
この章では、次の内容について説明します。
ユーザーが使用可能なすべてのリソースを消費しないようにするため、N1 Grid Engine 6.1 ソフトウェアは、グローバル、キュー、またはホスト層で設定可能なコンプレックス属性をサポートしています。この階層型のリソース管理手法は強力ではありますが、ギャップが生じます。多数のさまざまなカスタムリソース、ユーザーグループ、およびプロジェクトで構成される大規模な導入では特に重要な意味を持ちます。リソース割り当て機能は、ボトルネックリソースが不足したときに、あるプロジェクトまたは部署がそのリソースを譲るように制御して、こうした企業環境を管理できるようにすることで、このギャップを埋めます。
リソース割り当て機能によって、数種類のリソース、数種類のリソース消費者、クラスタ内のすべてのジョブ、また消費者の組み合わせに対して制限を適用することができます。この意味では、リソースは N1 Grid Engine 構成で認識されている、定義済みコンプレックス属性のすべてです。コンプレックス属性の詳細は、complex(5) のマニュアルページを参照してください。リソースには、slots、 arch、mem_total、num_proc、swap_total、組み込みリソース、あるいは compiler_license のようなカスタム定義のリソースを指定できます。リソース消費者は、ユーザー、キュー、ホスト、プロジェクト、および並列環境単位になります。
リソース割り当て機能は、消費者が任意の時点で使用可能なリソースを制限する手段を提供します。この制限は、ユーザー、部署、およびプロジェクトに優先順位を付ける間接的な手段になります。ユーザーがリソースを取得する優先順位を直接定義するには、「緊急度ポリシーの構成」および 「共有ベースポリシーの構成」で説明しているリソースの緊急度および共有ベースポリシーを利用します。
N1 Grid Engine 6.1 ソフトウェアを使用してリソースを制限するには、qquota および qconf コマンド、または QMON グラフィカルインタフェースを使用します。詳細は、qquota(1) および qconf(1) のマニュアルページを参照してください。
リソース割り当てセットを使用して、任意のジョブ要求に対して最大リソース消費量を指定することができます。リソース割り当てセットを定義すると、スケジューラはそのセットを利用し、割り当て量の超過がないことに注意しながら、次に実行可能なジョブを選択することができます。リソース割り当て量を設定することの最大の意味は、リソース割り当て量を超えないジョブだけがスケジューリングされて、実行されることです。
リソース割り当てセットでは、特定のジョブ要求に対する最大リソース割り当て量を定義します。構成された規則セットのすべてが、常に適用されます。複数のリソース割り当てセットが定義されている場合は、もっとも制限が厳しいセットが適用されます。リソース割り当てセットはどれも、1 つ以上のリソース割り当て規則で構成されます。これらの規則が順に評価され、特定の要求に合致する最初の規則が使用されます。つまり、リソース割り当てセットの中の 1 つのリソース割り当て規則が特定の要求に対する実効規則になります。
リソース割り当てセットは、次の情報で構成されます。
名前 (name) – リソース割り当てセットの名前。
有効 (enabled) – スケジューリングの判定時にリソース割り当てセットを考慮するかどうかを示すブール型値。enabled が true の場合は、リソース割り当てセットは有効になり、スケジューリングの判定時に考慮されます。デフォルト値は false です。
説明 (description) – セットを説明する任意の文字列 (省略可能)。デフォルト値は NONE です。
制限規則 (limit rule) – どのリソース割り当てセットにも、少なくとも 1 つの制限規則が必要です。この規則を limit フィールドに含めます。たとえば、次の制限規則はユーザー全体で最大スロット割り当て数を 10 個に制限します。limit users * to slots=10. 制限規則には、次の情報が含まれます。
名前 (name) – 規則の名前 (省略可能)。使用する場合は、リソース割り当てセット内で一意でなければなりません。
フィルタスコープ (filter scope) – この割り当てを適用するリソース消費者をリスト指定します。各リソース消費者は、1 つのキーワードのあとに消費者のコンマ区切りのリストで設定します。使用できるキーワードは次のとおりです。users、 projects、queues (クラスタキュー)、hosts、および pes (並列環境)。たとえば、users {user1, user2} はリソース消費者の例です。users {user1, user2} hosts * はフィルタスコープの例です。このフィルタスコープは、user1 および user2 に対する最大割り当て量をホストとは別に設定された制限の最大数に制限します。
リソース割り当て定義に拡張可能なリストを含めるには、リソース消費者リストを中括弧 {} で囲みます。
リストから特定のリソースタイプを除外するには、感嘆符 ! を使用します (「否定」記号とも呼ばれることがある)。
制限 (limit) – リソースに対する実際の制限を定義した属性と値のペア。例: virtual_free=2G。属性と値のペアはコンマで区切って複数指定することができます。例: virtual_free=2G,swap_free=1.5G。
次のリソース割り当てセット例は、user1 と user2 に対して、ホストグループ lx_hosts の各ホストの未使用仮想空間の最大割り当て量を 2 ギガバイトに制限します。
{ name max_virtual_free_on_lx_hosts description "resource quota for virtual_free restriction" enabled true limit users {user1,user2} hosts {@lx_host} to virtual_free=2g }
リソース割り当て規則では、必ず、使用可能なリソースの最大値を定義します。だいたいの場合、これらは静的であり、一致するすべてのフィルタスコープに対して同じです。いくつかの異なる規則を、異なるスコープに適用することもできますが、それらの規則はほぼ同じです。この場合は、規則を複製する代わりに、動的制限を定義できます。
動的制限では、代数式を使用して規則制限値を導出します。代数式でコンプレックス属性を参照し、その値を使用して制限値を計算することができます。
次は、動的制限の使用例です。ユーザーは、すべての Linux ホストで 1 CPU 当たり 5 つのスロットの使用が許可されます。
limit hosts {@linux_hosts} to slots=$num_proc*5 |
num_proc の値は、ホスト上のプロセッサ数です。制限は式 $num_proc*5 で求められ、ホストによって異なることがあります。上記の例を展開すると、たとえば次のような制限が考えられます。
CPU 2 つのホストの場合、ユーザーはジョブの実行に 10 個のスロットを使用できます。
CPU 1 つのホストの場合、ユーザーはジョブの実行に 5 個のスロットを使用できます。
num_proc の代わりに、負荷値あるいは消費可能リソースのいずれかとしてホストが認識するほかのコンプレックス属性をすべて使用することができます。
次のタスクは、QMON グラフィカルインタフェースを使用してリソース割り当て量を設定する例です。
「QMON Main Control」ウィンドウで「Resource Quota Configuration」ボタンをクリックします。
テキストフィールドにリソース割り当て情報を入力します。
次の画面例で示すように、qconf コマンドに対するのと同じ構文を使用してください。
qquota コマンドを使用して、現在の N1 Grid Engineリソース割り当てに関する情報を表示できます。qquota コマンドは、少なくとも 1 回使用されているか、静的制限を定義した各リソース割り当てを一覧表示します。qquota は、該当するリソース割り当てごとに次の情報を表示します。
リソース割り当て規則 – 規則セットの名前と規則の名前または個数
制限 – リソース名、およびそのリソースの使用可能数と使用数
フィルタ – 実効リソース割り当てセットフィルタ。「リソース割り当てセットについて」 で説明したフィルタスコープを適用することで決定されます。
qquota コマンドには、特定のホスト、クラスタキュー、プロジェクト、並列環境、リソースまたはユーザーに情報を絞り込むためのオプションがいくつかあります。オプションが使用されなかった場合、qquota は、コマンドの呼び出し元ユーザー名に該当するリソースセットの情報を表示します。詳細は、qquota(1) のマニュアルページを参照してください。
次の例は、ユーザー user1 に該当するリソース割り当てセットの情報を示しています。
$ qquota -u user1 resource quota limit filter -------------------------------------------------------------------------------- maxujobs/1 slots=5/20 - max_linux/1 slots=5/5 hosts @linux max_per_host/1 slots=1/2 users user1 hosts host2 |
qconf コマンドを使用して、リソース割り当てセットおよび規則を追加、変更、削除できます。
テキストエディタを呼び出して、リソース割り当てセットを追加する。
$ qconf -arqs [name] |
ファイル中にすでに定義されているセットを追加するには、qconf -Arqs filename を使用します。
エディタを呼び出して、リソース割り当てセットの情報を変更する。
$ qconf -mrqs [name] |
ファイルに含まれる情報を使用してセットを変更するには、 qconf -Mrqs filename [name] を使用します。
-mrqs または -Mrqs オプションで名前を指定しなかった場合は、現在設定されているすべての規則セットが新しい規則セットで置き換えられます。
リソース割り当てセットを削除する。
$ qconf -drqs [name_list] |
定義されているリソース割り当てセットを一覧表示する。
$ qconf -srqsl |
定義されている特定のリソース割り当てセットの詳細情報を表示する。
$ qconf -srqs [name_list] |
qconf の詳細は、 qconf(1) のマニュアルページを参照してください。
次の例は、リソース割り当てにさまざまなコマンドを使用する方法を示しています。例 6–4 に示す規則セットが定義している制限は、次のとおりです。
ユーザー全体でスロットの割り当て量が 20 個を超えてはならない。
各 Linux ホストで、ユーザー全員のスロット割り当ては最大 5 個。
ユーザー 1 人当たりのスロット割り当て量は Linux ホスト 1 台当たり 1 スロット。ただし、MyUser ユーザーの割り当て量は 2 つ。ほかのホストのすべてのスロットはゼロに制限。
ホストグループ @linux には、host1 および host2 がある。
この規則セットを設定するには、次の形式の qconf コマンドを使用します。
qconf -arqs <rule-set-name> (規則セットごと実行する場合)
qconf -arqs (すべての規則セットを一度に実行する場合)
複数のユーザーでジョブを発行すると、qstat コマンドは、例 6–5 に示すような情報を出力します。
{ name maxujobs limit users * to slots=20 } { name max_linux limit users * hosts @linux to slots=5 } { name max_per_host limit users MyUser hosts {@linux} to slots=2 limit users {*} hosts {@linux} to slots=1 limit users * hosts * to slots=0 }
$ qstat job-ID prior name user state submit/start at queue slots ja-task-ID --------------------------------------------------------------------------------------------- 27 0.55500 Sleeper MyUser r 02/21/2006 15:53:10 all.q@host1 1 29 0.55500 Sleeper MyUser r 02/21/2006 15:53:10 all.q@host1 1 30 0.55500 Sleeper MyUser r 02/21/2006 15:53:10 all.q@host2 1 26 0.55500 Sleeper MyUser r 02/21/2006 15:53:10 all.q@host2 1 28 0.55500 Sleeper user1 r 02/21/2006 15:53:10 all.q@host2 1 |
$ qquota # as user MyUser resource quota rule limit filter -------------------------------------------------------------------------------- maxujobs/1 slots=5/20 - max_linux/1 slots=5/5 hosts @linux max_per_host/1 slots=2/2 users MyUser hosts host2 max_per_host/1 slots=2/2 users MyUser hosts host1 $ qquota -h host2 # as user MyUser resource quota limit filter -------------------------------------------------------------------------------- maxujobs/1 slots=5/20 - max_linux/1 slots=5/5 hosts @linux max_per_host/1 slots=2/2 users MyUser hosts host2 $ qquota -u user1 resource quota limit filter -------------------------------------------------------------------------------- maxujobs/1 slots=5/20 - max_linux/1 slots=5/5 hosts @linux max_per_host/1 slots=1/2 users user1 hosts host2 $ qquota -u * resource quota limit filter -------------------------------------------------------------------------------- maxujobs/1 slots=5/20 - max_linux/1 slots=5/5 hosts @linux max_per_host/1 slots=2/2 users MyUser hosts host1 max_per_host/1 slots=2/2 users MyUser hosts host2 max_per_host/1 slots=1/2 users user1 hosts host2 |
キュー内のジョブおよびリソースの処理効率を最大限に高めるには、もっとも厳しい規則を規則セットの先頭に置きます。この仕様に従うと、N1 Grid Engineスケジューラが特に効率的な方法で適切なキューインスタンスの量を絞り込むのに役立ちます。なぜなら、先頭の規則は、同じ規則セット内の後続の規則に影響されることはなく、常にその規則の代表になるためです。
このことを具体的に理解するために、次のような環境を考えてみます。
4 つのキュー Q001 〜 Q004
4 つの管理対象リソース F001 〜 F004
F001 などの特定の管理対象リソースを要求するジョブは、Q001 などの関連付けられているキューで実行するよう制限されている
ジョブは 5 つあるプロジェクト P001 〜 P005 の 1 つに発行する
こうした環境で、次のような規則セットを 1 つ定義したと仮定します。
{ name 30_for_each_project description "not more than 30 per project" enabled TRUE limit projects {*} queues Q001 to F001=30 limit projects {*} queues Q002 to F002=30 limit projects {*} queues Q003 to F003=30 limit projects {*} queues Q004 to F004=30 limit to F001=0,F002=0,F003=0,F004=0 } |
この 1 つの規則セットは、プロジェクト 1 つ当たりの各管理対象リソースの使用量を 30 に制限し、同時に適格のキュー内のジョブを制限します。この規則は問題なく機能しますが、多数のホストからなる大規模なクラスタでは、ジョブの割り当てに時間がかかる原因になります。
N1 Grid Engineスケジューラが仲介中にできるだけ多くのキューインスタンスを除外できるようにするには、この単一規則セットを 4 つの規則セットに分ける方が優れています。
{ name 30_for_each_project_in_Q001 description "not more than 30 per project of F001 in Q001" enabled TRUE limit queues !Q001 to F001=0 limit projects {*} queues Q001 to F001=30 } { name 30_for_each_project_in_Q002 description "not more than 30 per project of F002 in Q002" enabled TRUE limit queues !Q002 to F002=0 limit projects {*} queues Q002 to F002=30 } { name 30_for_each_project_in_Q003 description "not more than 30 per project of F003 in Q003" enabled TRUE limit queues !Q003 to F003=0 limit projects {*} queues Q003 to F003=30 } { name 30_for_each_project_in_Q004 description "not more than 30 per project of F004 in Q004" enabled TRUE limit queues !Q004 to F004=0 limit projects {*} queues Q004 to F004=30 } |
この 4 つの規則セットは、単一の規則セットと同じプロジェクト単位のリソース割り当て量制限を課します。しかし、4 つの規則セットは、不適切なキューインスタンスが最初にシールドされているため、ずっと効率的に処理できます。この場合、これらのシールドを 1 つのリソース割り当てセットにまとめることはできません。
前述の例の目的は、リソース 1 つ当たりクラスタキュー 1 つを推奨することではありません。実際は、その逆です。次に示すように、キューを少なくすることで、常にシールドをより少なく、より強力にできます。
{ name 30_for_each_project_in_Q001 description "not more than 30 per project of F001/F002 in Q001" enabled TRUE limit queues !Q001 to F001=0,F002=0 limit projects {*} queues Q001 to F001=30,F002=30 } { name 30_for_each_project_in_Q002 description "not more than 30 per project of F003/F004 in Q002" enabled TRUE limit queues !Q002 to F003=0,F004=0 limit projects {*} queues Q002 to F003=30,F004=30 } |
この例では、キューが Q001 〜 Q004 から Q001 〜 Q002 に整理されています。しかし、実際にはこうすることで、クラスタ全体の稼働率とスループットが向上します。