印刷用ページ       送信     
クリックして評価とフィードバックをお寄せください
MSDN
MSDN ライブラリ
テクニカルドキュメント
.NET 開発
patterns & practices
 第 17 章 「.NET アプリケーション パフォーマンスのチューニン...
第 17 章 「.NET アプリケーション パフォーマンスのチューニング」

Patterns and Practices ホーム

.NET アプリケーションのパフォーマンスとスケーラビリティの向上

J.D. Meier, Srinath Vasireddy, Ashish Babbar, and Alex Mackman
Microsoft Corporation

May 2004
日本語版最終更新日 2005 年 11 月 20 日

要約: この章は、3 つのパフォーマンス チューニング カテゴリである、システム、プラットフォーム、アプリケーションの説明から始めます。その後、反復的なパフォーマンス チューニングのプロセスを提示します。また、ベースライン メトリクスから開始し、一度のチューニングに一組の構成変更を適用し、テストと計測を実施してその変更がうまく機能したかどうかを判断するという一連のサイクルの重要性を説明します。その後の節では、ASP.NET、Web サービス、Enterprise Services および ADO.NET のチューニング方法、そして CPU、メモリ、ディスク I/O およびネットワーク I/O を含む、共有システム リソースのチューニング方法を説明します。それぞれのケースにおいて、ボトルネックを特定し除去する方法を説明します。

目次

目的
概要
この章の使いかた
チューニングのカテゴリ
パフォーマンス チューニングのプロセス
ボトルネックの特定
システムのチューニング
CPU
メモリ
ディスク I/O
ネットワーク I/O
.NET Framework のチューニング
CLR のチューニング
ASP.NET のチューニング
Enterprise Services のチューニング
Web サービスのチューニング
リモート処理のチューニング
ADO.NET のチューニング
SQL Server のチューニング
インターネット インフォメーション サービス (IIS) のチューニング
まとめ
補足資料

目的

  • 規範的なパフォーマンス チューニングのプロセスを使う。
  • アプリケーションとシステムに関するボトルネックを特定する。
  • CPU、メモリ、ディスク I/O、ネットワーク I/O を含む、システムのチューニングを行う。
  • プラットフォームとアプリケーションをチューニングする。
  • Microsoft(R) .NET Framework の構成を設定する。
  • ASP.NET アプリケーションと Web サービスをチューニングする。
  • Enterprise Services アプリケーションをチューニングする。

概要

パフォーマンス チューニングとは、ボトルネックを特定し、システム的に除去して、パフォーマンスを改善することを意味します。この章は、チューニングの焦点を構成設定に合わせているため、管理者と開発者の両方にとって重要な章といえます。この章では、ボトルネックの特定方法と、そのボトルネック除去のための適切な構成変更の適用方法について説明します。コードの最適化は、このガイドのパート III 「アプリケーションのパフォーマンスとスケーラビリティ」に含まれる、テクノロジに特化した章で扱います。

この章は、3 つのパフォーマンス チューニング カテゴリである、システム、プラットフォーム、アプリケーションの説明から始めます。その後、反復的なパフォーマンス チューニングのプロセスを提示します。また、ベースライン メトリクスから開始し、一度のチューニングに一組の構成変更を適用し、テストと計測を実施してその変更がうまく機能したかどうかを判断するという一連のサイクルの重要性を説明します。

その後の節では、ASP.NET、Web サービス、Enterprise Services および ADO.NET のチューニング方法、そして CPU、メモリ、ディスク I/O およびネットワーク I/O を含む、共有システム リソースのチューニング方法を説明します。それぞれのケースにおいて、ボトルネックを特定し除去する方法を説明します。

この章の使いかた

この章を最大限に活用するために、以下に留意してください。

  • 第 16 章「Testing .NET アプリケーション パフォーマンスのテスト」を読む - この章を読む前に、必ず第 16 章を読んでください。
  • 第 15 章「.NET アプリケーション パフォーマンスの計測」を使う - この章で説明する手順を実行する前に、ボトルネック原因を特定するのに必要な計測関連の詳細情報を記載する第 15 章を利用できるようにしておきます。
  • 第 3 章「アプリケーション パフォーマンスのための設計ガイドライン」を読む - 設計時にボトルネックを取り込まないようにするため、第 3 章を読んでください。
  • 第 4 章「.NET アプリケーションのパフォーマンスとスケーラビリティのためのアーキテクチャと設計のレビュー」を読む - 特定のアーキテクチャあるいは設計に関する判断がに起因する潜在的なボトルネックを特定しやすくするため、第 4 章を読んでください。
  • テクノロジ関連の章を読む - パート III「アプリケーションのパフォーマンスとスケーラビリティ」の章を読んで、コードの最適化を行う方法と、コードの作成方法が適切でないために生じるボトルネックを回避する方法を学習してください。

チューニングのカテゴリ

構成とチューニングの設定は、以下のカテゴリに分類できます。このカテゴリにチューニングの焦点を合わせてください。

  • アプリケーション - アプリケーションの構成パラメータを含みます。

    .NET アプリケーションの構成パラメータは、主に構成ファイル内にあります。ASP.NET アプリケーションは Web.config 構成ファイルを使用します。

  • プラットフォーム - ホストのオペレーティング システム、.NET Framework、インターネット インフォメーション サービス (IIS) や Microsoft SQL Server(TM) などの Web サーバーとデータベース サーバーを含みます。.NET Framework の構成は Machine.config ファイルで保持されています。サーバー上の .NET アプリケーションはすべて、このファイルの設定内容による影響を受けます。
  • システム - サーバー上の ハードウェア リソースを含みます。このようなリソースには、CPU、メモリ、ディスク I/O およびネットワーク I/O があります。

図 17.1 に、パフォーマンス チューニングの 3 つのカテゴリの要約を示します。

パフォーマンス チューニングのカテゴリ

図 17.1: パフォーマンス チューニングのカテゴリ

チューニングには、サーバー間における規定値の事前チューニングや、さらにバースト負荷のかかる状況など特定のアプリケーション シナリオに対するチューニングが含まれます。このプロセスでは、すべてのサーバー間ではなく、特定のサーバー上の構成設定に対するチューニングを必要とする場合があります。あるサーバーに固有の構成ファイルにチューニングを行い、その後そのファイルを別のサーバーに移動させると、再チューニングが必要となることがよくあります。たとえば、ASP.NET におけるスレッド プールのチューニングは、導入された CPU の数によって左右されます。構成ファイルを 2 つの CPU をもつサーバーから 4 つの CPU をもつサーバーに移動するような場合は、再チューニングが必要です。

パフォーマンス チューニングのプロセス

ボトルネックを特定し、構成を変更し、再度計測を行います。基本的なパフォーマンス チューニング プロセスを図 7 に示します。

パフォーマンス チューニングは、ボトルネックを識別・除去するための反復的プロセスで、アプリケーションがパフォーマンス目標値を満足させるまで実施します。ベースラインを設定することからスタートします。次に、データを収集し、結果を分析し、その分析結果を基に構成を変更します。変更を実施するたびに、再テストと計測を実施し、アプリケーションが、パフォーマンス上の目標値に近づいていることを確認します。目的は、アプリケーションに対し、負荷テスト、ストレス テスト、キャパシティ テストを実施することではなく、さまざまなチューニング オプションと構成設定が、アプリケーションにどのような影響を与えるのかを理解することにあります。図 17.2 に、基本的なチューニング プロセスを示します。

パフォーマンス チューニング プロセス

図 17.2: パフォーマンス チューニング プロセス

チューニング プロセスは以下の手順で構成される、反復的な処理です。

  1. ベースラインの設定 - パフォーマンス目標、テスト プラン、ベースライン メトリクスを明確に定義してください。
  2. データの収集 - 負荷をシミュレートし、メトリクスを取り込みます。
  3. 結果の分析 - パフォーマンスの問題点とボトルネックを特定します。
  4. 構成 - 新規のシステム、プラットフォームまたはアプリケーションの構成設定を適用して、アプリケーション設定をチューニングします。
  5. テストと計測 - テストと計測を実施し、構成変更が有効だったことを確認します。

1. ベースラインの設定

アプリケーションのチューニングを開始する前に、ベースラインを設定しておく必要があります。以下を明確に定義してください。

  • パフォーマンス目標値

    アプリケーションのパフォーマンス目標値は、通常は、応答時間、スループット (毎秒の処理要求数)、リソース使用レベルといった観点で測定されます。この目標値には、特定のシナリオのバジェット化回数と、アプリケーションに割り当てた、CPU、メモリ、ディスク I/O およびネットワーク I/O などのリソースの使用レベルが含まれます。パフォーマンス目標値の設定に関する詳細情報は、このガイドの「パフォーマンスに関するベスト プラクティス一覧」を参照してください。

  • テスト プランとテスト スクリプト

    アプリケーションに負荷をかけるためのテスト プランと一式のテスト スクリプトが必要です。テストを実行するための詳細情報は、第 16 章「.NET アプリケーション パフォーマンスのテスト」を参照してください。

  • ベースライン メトリクス

    システム、プラットフォーム、アプリケーションについて、一式のベースライン メトリクスを必ず取得してください。ベースライン メトリクスを使うことで、パフォーマンス チューニング プロセスにおいて、構成に加えた変更の影響を評価できます。メトリクスについての詳細情報は、第 16 章「.NET アプリケーション パフォーマンスのテスト」の「メトリクス」を参照してください。

2. データの収集

Microsoft Application Center Test (ACT) などのツールを使って負荷をシミュレートします。システム モニタあるいは Microsoft Operations Manager などのツールを使うと、パフォーマンス カウンタを取得できます。

初めてテストを実行するときは、ベースライン メトリクスの設定に使用したバージョンのアプリケーションを使用します。その後チューニング プロセスを反復する際は、構成だけを変更し、最初のテストと同一のワークロードとテスト スクリプトを用いてパフォーマンスをテストします。

一定のワークロードを使う

チューニング プロセスの反復時は、必ず同一のテスト スクリプトと一定のワークロードを使用してください。そうすることで、適用した構成変更による影響を正確に計測できます。

短期間のテストを実施するときは、テスト スクリプトに適切なウォームアップ時間を含めます。ジャスト イン タイム (JIT) コンパイル、キャッシュへの投入などにより初期応答時間が遅くなることが原因でテスト結果が歪曲されないようにします。また、テストは、十分かつ現実的な期間実施してください。

ACT の使用についての詳細情報は、このガイドの「How To 情報」にある「パフォーマンス / スケーラビリティ テストのための ACT の使用方法」と「Web サービス パフォーマンス テストのための ACT の使用方法」を参照してください。

結果をフォーマット化する

標準的なテストでは、さまざまなソースから、さまざまなフォーマットで、さまざまなロケーションにおいて、膨大な量のデータが作成されます。たとえば、取得するデータとしては、すべてのサーバーからのシステム パフォーマンス カウンタ、Web サーバーおよびアプリケーション サーバーからの IIS ログ ファイル、データベース サーバー上の SQL Server メトリクスなどがあります。データをまとめて、次の手順に備えてフォーマット化し、結果を分析する必要があります。

データのフォーマット化は、アプリケーション構成の一部に加えた変更のカスケード効果がマッピングできるような方法で行います。データを前述したカテゴリ (システム、プラットフォーム、アプリケーション) 毎に整理することで、アプリケーションの個々の部分ではなく、アプリケーション全体の分析が可能になります。

構成上の変更が、どのようなカスケード効果をもたらすのかを説明する例として、Web サーバーのスレッド プール設定を変更すると、要求の処理が高速になることがありますが、それはつまり、データベース サーバー上のリソース使用率 (CPU、メモリ、ディスク I/O) のレベルを上げてしまう可能性があるということでもあります。

3. 結果の分析

このステップでは、取得データを分析し、パフォーマンス問題とボトルネックを特定します。問題の真因を特定するため、その兆候に初めて気づいた時点でトレースを実施します。多くの場合、目に見える現象は問題の原因ではありません。データ分析時は、以下の点に留意してください。

  • 収集中のデータは、通常は、問題の指標でしかなく、問題の原因を示すものではありません。パフォーマンス カウンタなどのインジケータを使えば、デバッグ プロセスやトラブルシューティング プロセスを分離して、機能の特定のカテゴリに的を絞る方法が示唆されます。
  • パフォーマンス カウンタが示す、値の一時的な急上昇は、大きな問題ではありません。納得できるものであれば、例外的なものは無視してください。
  • テスト結果がウォームアップ時間によって歪曲されないようにしてください。また、メトリクス取得にいたるまでの一定の期間、テスト スクリプトを実行してください。
  • 収集するデータが完全なものでなければ、分析も不正確なものになる恐れがあります。再テストを実施し、欠落情報を収集、あるいは別の分析ツールを使用しなければならない場合もあります。たとえば、共通言語ランタイム (CLR) のパフォーマンス カウンタによる分析で、ジェネレーション 2 のガベージ コレクションが大量に発生していることが示されている場合、CLR プロファイラ ツールを使って、アプリケーション全体のメモリ使用パターンをプロファイリングする必要があります。
  • さらにチューニングを必要とするカテゴリを特定し、分離することが可能でなければなりません。これは、変更のためのコードと設計の最適化がすでに終了していて、構成のみがチューニングを必要としているということが前提です。
  • パフォーマンス チューニング中は、現在取得している結果を、以前の結果あるいはパフォーマンスのベースライン メトリクスと比較する必要があります。
  • 分析中、ボトルネックあるいはパフォーマンス上の問題点を特定できたときは、それらに優先順位をつけ、最も大きな影響を及ぼすと思われるものから取り組んでください。テスト実行後、最初に遭遇したボトルネックを基に、優先順位のリストを作成してもかまいません。
  • 分析を文書化します。発見事項、発見場所、および問題を解決するための構成変更の適用方法を含む、推奨事項を記録します。

4. 構成

アプリケーション設定のチューニングは、新規のシステム、プラットフォームあるいはアプリケーションの構成設定を適用することで行います。以前のステップからの分析文書には、推奨事項が記載されていると考えられるので、構成上の変更を適用する時は、以下のガイドラインを活用してください。

  • 一度に一組の変更を適用する - 変更は個々に扱います。複数の構成上の変更を加えると、結果が歪曲され、新しく生じた潜在的なパフォーマンス問題の特定が困難になることがあります。ひとつの変更が、実際には、単体として適用し、評価を受ける必要のある複数の構成上の変更を含む場合があります。
  • 問題点は優先順位をつけて解決する - 最大の効果を得られると考えられる問題から取り組みます。たとえば、ASP.NET の微調整の代わりに、データベース テーブル上に、欠落していると推定するインデックスを作成することで、より良い初期結果を得られる可能性があります。

5. テストと計測

パフォーマンス チューニングは、反復すべきプロセスです。ある構成上の変更を適用した後は、その変更に効果があったかどうかを確認するための再テストと計測を行います。アプリケーションがそのパフォーマンス目標値を満足させるまで、あるいはコードの最適化や設計変更などの代替案の採用を決定するまでは、このプロセスを継続します。

ボトルネックの特定

アプリケーションのライフサイクル初期における不適切な設計や実装によるボトルネックを特定する必要があります。最適化やチューニングの対象とはなりえないボトルネックを、ライフサイクルの設計段階での制約事項として特定することで、パフォーマンスへの悪影響を最小限とするよう、設計に盛り込むことが可能になります。

ボトルネックとは何か?

ボトルネックとは、スループットを制約するデバイスまたはリソースのことです。ほとんどの場合、アプリケーションにおけるパフォーマンス上のボトルネックは、CPU、メモリ、ディスク I/O 、ネットワーク I/O などのサーバー リソースや、使用可能なデータベース接続またはネットワーク帯域幅などの他の外部リソースを含むリソースの問題に関連するものです。

ボトルネックは、サーバー ロールに基づき、レイヤごとに異なります。

  • Web / アプリケーション サーバー - ボトルネックの代表的な原因としては、効率の悪いセッションと状態管理、スレッド競合、Web サービスまたはデータベースへの所要時間の長い呼び出し、呼び出しの多いインターフェイスがあります。
  • データベース サーバー - ボトルネックの代表的な原因としては、テーブル設計やテーブルの正規化がよくない、テーブル上のインデックスの効率が悪い、テーブル間のデータ分割が適切ではないなどの、不充分な論理データベース設計があります。他にも、非効率なクエリの効率が悪い、クエリにおいてトランザクションが使う分離レベルが適切ではない、ストアド プロシージャの効率が悪いなどの原因があります。

ボトルネックの特定方法

ボトルネック特定における最初のステップは、アプリケーションに対する、さまざまなユーザー負荷とアクセス パターンをシミュレートするため実施する、多種のテストおよび計測を理解することです。以下の計測は、ボトルネックを顕在化させ、チューニングを要するカテゴリを区別するのに役立ちます。

  • ユーザー負荷に対する、応答時間、スループット、リソース使用率を計測する。
  • アプリケーションについて、より高い粒度のビューを取得するためのメトリクスを計測する。

ユーザー負荷に対する、応答時間、スループット、リソース使用率を計測する

これらのメトリクスを使うと、チューニング プロセスを反復するうちに、パフォーマンス目標値に近づいているのか、あるいは遠ざかっているのかを確認できます。また、これらのメトリクスで、どのリソースがアプリケーションにとっての最初のボトルネックになるのか、また、どのサーバー上でボトルネックが発生するのかについて、おおまかに把握することができます。

ユーザー負荷に対する応答時間を分析する

ユーザー数を変えながら応答時間を計測するときは、応答時間における急上昇に注意してください。この上昇が、効率の悪さを示すポイントです。図 17.3 で示すように、このポイント以降は、パフォーマンスは低下する一方です。

ユーザー負荷に対する応答時間

図 17.3: ユーザー負荷に対する応答時間

ユーザー負荷に対するスループットを計測する

ユーザー負荷に対するスループットを計測するときは、スループットのピークに注意してください。スループットが低下するポイントで、ボトルネックに遭遇したと考えます。このポイント以降は、パフォーマンスは低下を続けます。図 17.4 に例を示します。

ユーザー負荷に対するスループット

図 17.4: ユーザー負荷に対するスループット

ユーザー負荷に対するリソース使用率を分析する

線形に増加するユーザー負荷に対するリソース使用レベルを分析します。新規ユーザーが追加され、多くのトランザクションが実行されるにつれ、リソース使用レベルが急上昇するかどうかを確認します。図 17.5 に、ユーザー負荷に対する線形の使用レベルを示します。

ユーザー負荷に対するリソース使用率

図 17.5: ユーザー負荷に対するリソース使用率

アプリケーションについて、より高い粒度のビューを取得するためのメトリクスを計測する

前述したパフォーマンス目標値についての、粒度の粗い監視からの入力を使って、チューニング プロセスの反復時にカウンタを追加することができます。

前述の例を使うと、リモートのデータベース呼び出しの実行中であれば、そのデータベース呼び出し終了までの時間を計測できます。データベース上のインデックス、ロック、スキャンしたテーブルの数、リソース使用レベルなどに関連するメトリクスを監視して、クエリの実行に長い時間がかかる理由を特定します。

詳細情報

スループット計測、負荷テスト、ユーザー負荷の生成についての詳細情報は、第 15 章「.NETアプリケーション パフォーマンスの計測」と第 16 章「.NET アプリケーション パフォーマンスのテスト」を参照してください。

システムのチューニング

アプリケーション、サービスおよびオペレーティング システムが、いかに効率よく共有システム レベルのリソースを使っているか、ということが、スループット、キューイング、応答時間に直接的な影響を及ぼします。システム モニタなどのツールを使うことで、リソース使用率を監視することができます。最低限、以下の共有コンポーネントについては監視が必要です。

  • CPU
  • メモリ
  • ディスク I/O
  • ネットワーク I/O

CPU

サーバー上で実行されるすべてのアプリケーションは、それぞれ CPU からタイム スライスを割り当てられます。CPU は、コンピュータ上で実行されるすべてのプロセスを効率的に処理できる、もしくは負荷が高すぎる状態になっています。プロセッサの動作と、スレッド作成、スレッド切り替え、コンテキスト切り替えなど個々のプロセスの動作を検討することで、プロセッサのワークロードとパフォーマンスを把握することができます。

メトリクス

表 17.1 のパフォーマンス カウンタを使ってプロセッサのボトルネックを特定します。

表 17.1: CPU のボトルネックを特定するのに使うパフォーマンス カウンタ

カテゴリカウンタ
Processor
(プロセッサ)
% Processor Time
% Privileged Time
System
(システム)
Processor Queue Length
Context Switches/sec

これらのカウンタの計測方法、しきい値および意味についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「プロセッサ」を参照してください。

個々のプロセスを監視するか、すべてのインスタンスに対して _Total を使うことができます。 プロセッサ動作の値が高い場合は、プロセッサに過剰に高い負荷がかかっていることを示すことがあります。プロセッサ キューが長期に渡って保持されている場合は、プロセッサのボトルネックが存在する確立が高くなっています。マルチプロセッサ サーバー内のひとつのプロセッサに負荷がかかり過ぎている場合は、そのプロセッサを使っているシングル スレッド アプリケーションがあるということを意味することがあります。

メモ: プロセッサの使用率は、システムとアプリケーションの特性によって左右されます。「ボトルネック」 (次の節) で説明するしきい値 75% は、標準的な観察事項をベースにしたものです。システム特性をベースにして、しきい値を増減させます。

ボトルネック

以下の場合は、CPU のボトルネックが存在する可能性があります。

  • Processor\ % Processor Time が 75% のしきい値をたびたび超える。
  • System\ Processor Queue Length が示す延長期間、保持されるキュー数が 2 である。
  • Processor\ % Privileged Time あるいは System\Context Switches/sec の値が以上に高い。

% Processor Time の値が高い場合は、キューイングが発生し、ほとんどのシナリオにおいて、System\ Processor Queue Length の値も高くなっています。図 17.6 に、プロセッサ時間とプロセッサ キュー長の両方の値が高くなっている、システム モニタのグラフを示します。

プロセッサ時間とプロセッサ キュー長の値が高くなっているシステム モニタのグラフ

図 17.6: プロセッサ時間とプロセッサ キュー長の値が高くなっているシステム モニタのグラフ

次のステップでは、どのプロセスが、値の急上昇の原因になっている (あるいはプロセッサ時間を消費している) のかを特定します。タスク マネージャを使い、Processes ページの CPU 列を確認すれば、CPU を高いレベルで消費しているプロセスを特定できます。Process\%Processor Time を監視し、監視対象のプロセスを選択することでも特定ができます。たとえば、図 17.7 に示すシステム モニタ出力から、ASP.NET ワーカー プロセスが、プロセッサ時間の大部分を消費していることがわかります。

ASP.NET ワーカー プロセスがプロセッサ時間の 98% 以上を消費していることを示すシステム モニタ出力

図 17.7: ASP.NET ワーカー プロセスがプロセッサ時間の 98% 以上を消費していることを示すシステム モニタ出力

チューニング オプション

CPU がボトルネックであると判断した場合は、以下の選択肢があります。

  • マルチ スレッド アプリケーションであれば、複数のプロセッサを追加します。シングル スレッド アプリケーションであれば、より強力なプロセッサへのアップグレードを検討します。
  • コンテキスト切り替えの発生レベルが高い場合は、プロセッサを増やす前に、プロセスのスレッド数を減らすことを検討します。
  • CPU 使用率の高いアプリケーションについては、分析し、チューニングを行います。ADPLUS ユーティリティを使って実行中のプロセスをダンプし、Windbg を使って原因を分析できます。このようなユーティリティは、Windows デバッギング ツールキットに含まれています。これらのツールはダウンロードが可能です ( http://www.microsoft.com/japan/whdc/devtools/debugging/default.mspx )。
  • アプリケーションが作成する監視機能ログを分析し、実行時間がもっとも大きなサブシステムを分離します。展開においてチューニングを実施するのではなく、実際にコード レビューを必要としているかどうかを確認します。

メモ: タスク マネージャを使うか、コマンド プロンプトから、アプリケーションの処理の優先順位を変更することはできますが、通常はこのような方法は回避すべきです。ほとんどの場合、上記選択肢のいずれかを適用すべきです。

メモリ

メモリは物理メモリと仮想メモリで構成されています。アプリケーションにどれくらいの量のメモリを割り当てるのかを検討する必要があります。メモリ関連のボトルネックの評価時は、不要な割り当て、効率の悪いクリーンアップ、不適切なキャッシングや状態管理のメカニズムについて検討します。メモリ関連のボトルネックを解消するには、コードを最適化して、それらの問題を除去し、アプリケーションに割り当てたメモリ量をチューニングしてください。チューニング中に、メモリ競合や過度なページ処理が発生していると判断できる場合は、物理メモリをサーバーに追加する必要があるかもしれません。

メモリの値が低いと、ページ処理が増加し、アプリケーションの仮想アドレス空間のページがディスクへと書き込まれます。過度なページ処理が行われると、ページ スラッシングが発生し、負荷の高いディスク I/O がシステム パフォーマンス全体を低下させます。

構成の概要

メモリ チューニングは以下の要素で構成されています。

  • アプリケーションにメモリ ボトルネックが存在するかどうかを判断します。存在する場合は、メモリを増設します。
  • 割り当てが制御可能であれば、メモリの割り当て量をチューニングします。たとえば、ASP.NET および SQL Server のメモリ割り当て量はチューニング可能です。
  • ページ ファイルのサイズをチューニングします。

メトリクス

表 17.2 に示すパフォーマンス カウンタを使って、メモリ ボトルネックを特定できます。結論を出す前に、24 時間以上にわたって、これらのカウンタ値をログ ファイルに記録してください。

表 17.2: メモリ ボトルネックを特定するのに使うパフォーマンス カウンタ

カテゴリカウンタ
Memory
(メモリ)
Available MBytes
Page Reads/sec
Pages/sec
Cache Bytes
Cache Faults/sec
Server
(サーバー)
Pool Nonpaged Failures
Pool Nonpaged Peak
Cache
(キャッシュ)
MDL Read Hits %

これらのカウンタの計測方法、しきい値と意味についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「CLR とマネージ コード」にある「メモリ」を参照してください。

ボトルネック

Available MBytes 値が低いときは、システム メモリが制約されている、あるいはアプリケーションがメモリを解放しないため、システムの物理メモリが不足していることを示しています。Monitor each 各プロセス オブジェクトの作業セット カウンタを監視します。プロセスがアクティブではないのに Available MBytes 値が高い場合は、オブジェクトがメモリを開放していない可能性があります。この時点で、CLR プロファイラ ツールを使い、メモリ割り当てに関する問題の原因を特定します。詳細情報については、このガイドの「How To 情報」にある「CLR プロファイラの使用方法」を参照してください。

Pages/sec 値が高いときは、アプリケーションに十分なメモリがないことを示しています。Page Reads/sec の平均値で割った、Pages Input/sec の平均値は、ディスク読み取りごとのページ数を示します。この値は、通常は毎秒 5 ページを超えてはならず、超えた場合は、システムがページ処理に時間を費やしすぎて、(アプリケーションが既に最適化されていることを前提として) さらにメモリを要求していることを示しています。図 17.8 のシステム モニタのグラフは、メモリ不足を示しています。

メモリ不足

図 17.8: メモリ不足

チューニング オプション

アプリケーションにメモリに関する問題があると判断したら、選択肢としては、メモリの増設、不要なサービスの停止、不要なプロトコルやドライバの削除があります。チューニングに関する考慮事項には以下があります。

  • いつメモリを増設するかを決める。
  • ページ ファイルを最適化する。

いつメモリを増設するかを決める

過度なページ処理がディスク動作に与える影響を判断するため、Physical Disk\ Avg. Disk sec/Transfer カウンタと Memory\ Pages/sec カウンタの値を掛けてください。この積が、0.1 を上回る場合は、ディスク アクセス時間の 10% 以上がページ処理によって消費されています。この状況が長時間に渡って発生する場合は、メモリの増設が必要になるでしょう。システムのメモリをアップグレードした後は、計測と監視を再度実行してください。

メモリを節約するため、以下に留意してください。

  • 使用していないサービスを停止する - 通常は使用しないサービスを停止することで、メモリを節約し、システム パフォーマンスを改善することができます。
  • 不要なプロトコルとドライバを削除する - 使われていないプロトコルであっても、ページ処理されている、あるいはページ処理されていないメモリ プール内のスペースを使います。ドライバもメモリを消費します。したがって、不要なプロトコルやドライバがあれば削除します。

ページ ファイルを最適化する

サーバーの仮想メモリのパフォーマンスを改善するため、ページ ファイルを最適化する必要があります。物理メモリとページ ファイルの組み合わせを、システムの仮想メモリと呼びます。システムに、プロセスを実行するのに十分な物理メモリがないときは、拡張メモリ源としてディスク上のページ ファイルが使用されます。この方法は、パフォーマンスを低下させます。ページ ファイルの最適化を行うには、以下のガイドラインにしたがってください。

  • システム上のページ ファイルのサイズを、使用できる物理メモリの 1.5 倍まで大きくします。ただし最大でも 4,095 MB 以内とします。システム クラッシュの際は、物理メモリのページ ファイルへの書き込みが可能となるよう、少なくとも物理メモリと同程度までページ ファイルを、大きくする必要があります。
  • ページ ファイルが、規定のパーティティション上で断片化されないようにします。
  • データ ファイルとページ ファイルを別々のディスクに分離するのは、I/O 処理数が多すぎてディスクがボトルネックになってしまっている場合に限ります。これらのファイルは、同一の物理ドライブの、同一の論理パーティション上にあるべきで、そうすることで、データ ファイルとページ ファイルが物理的に近い位置となり、2 つの異なる論理ドライブ間でのシークに時間を費やす必要がなくなります。

ページ ファイルのサイズを設定するには

  1. コントロール パネルを開きます。
  2. [システム] アイコンをダブルクリックします。
  3. [詳細設定] タブを選択します。
  4. [パフォーマンス オプション] をクリックします。
  5. [変更] をクリックします。[仮想メモリ] ダイアログボックスが表示されます (図 17.9 参照)。

    仮想メモリ設定

    図 17.9: 仮想メモリ設定

  6. [初期サイズ] と [最大サイズ] に値を入力します。[設定] をクリックし、[OK] をクリックします。

詳細情報

ページ ファイルのロケーションとパーティションについての詳細情報は、Microsoft サポート技術情報の Knowledge Base の文書 197379 「最適化と回復用にページ ファイルを設定する」 ( http://support.microsoft.com/default.aspx?scid=kb;ja;197379 ) を参照してください。

ディスク I/O

ディスク I/O とは、アプリケーションが、サーバー内にインストールされている、ひとつあるいは複数の物理ディスク上で実行する、読み取り処理および書き込み処理の数です。ディスク I/O に関連するボトルネックの原因となる一般的な動作には、所要時間の長いファイル I/O 処理、データの暗号・複合化、データベース テーブルからの不要データの読み取り、過剰なページ処理を引き起こす物理メモリの不足などがあります。低速のハード ディスクも考慮すべき要因です。

ディスク関連のボトルネックを解消するには、以下のガイドラインにしたがってください。

  • まず、アプリケーションにおける冗長なディスク I/O 処理を削除します。
  • システムが物理メモリ不足となっているかどうかを確認し、そうなっているときは、メモリを増設するか、過度なページ処理を回避します。
  • データを複数のディスクに分けることが必要かどうかを確認します。
  • 上記の対策を取っても、ディスク I/O 関連のボトルネックが解消しない場合は、高速ディスクへのアップグレードを検討します。

構成の概要

Microsoft Windows(R) 2000 では、プログラムとデータをディスクから取得します。ディスク サブシステムは、I/O パフォーマンスにおける最重要側面となリ得ますが、メモリ不足など他の要因によって問題点が隠れてしまう場合があります。パフォーマンス コンソール ディスク カウンタは、LogicalDisk オブジェクトと PhysicalDisk オブジェクトの中にあります。

メトリクス

表 17.3 に示すパフォーマンス カウンタを使って、ディスク I/O に関するボトルネックを特定できます。

表 17.3: ディスク I/O ボトルネックを特定するのに使うパフォーマンス カウンタ

カテゴリカウンタ
PhysicalDisk
(物理ディスク)
Avg. Disk Queue Length
Avg. Disk Read Queue Length
Avg. Disk Write Queue Length
Avg. Disk sec/Read
Avg. Disk sec/Transfer
Disk Writes/sec

これらのカウンタの計測方法、しきい値および意味についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「ディスク I/O」を参照してください。

メモ: ディスク パフォーマンスに関するボトルネックを分析するには、常に物理ディスク カウンタを使用する必要があります。Windows 2000 では、デフォルト設定において、物理ディスク カウンタは有効、論理ディスク カウンタは無効となっています。ソフトウェア RAID 使用時は、以下のコマンドを使って、論理ディスク カウンタを有効化する必要があります。

DISKPERF -YV

チューニング オプション

ディスク I/O がボトルネックであると判断した場合は、以下の選択肢があります。

  • ディスクを最適化する - Disk Defragmenter システム ツールを使います。
  • Windows 2000 上で Diskpar.exe を使用して、ディスク上のトラックとセクタの断片化によるパフォーマンス ロスを少なくします。Diskpar.exe は Windows 2000 リソース キットにあります。
  • ストライプ セットを使って、複数のディスクで同時に I/O 要求を処理する - 使用するタイプは、データ整合性についての要件によって異なります。読み取り中心のアプリケーションで、フォールト トレランスを必要とするものであれば、RAID 5 ボリュームを検討します。フォールト トレランスと、全体的に高い I/O パフォーマンスを得るには、ミラー化ボリュームを使います。フォールト トレランスを必要としないときは、読み取り・書き込みの高速化およびストレージ容量の改善のために、ストライプ セットを使います。ストライプ セット使用時は、ボリューム間で作業を分散するため、ディスクごとのディスク使用率が下がり、全体のスループットが増大します。

    ストライプ セットにおいてディスクを増設しても、スループットが向上しない場合、システムは、ディスク アダプタにおけるディスク間競合により発生したボトルネックに遭っていると考えられます。負荷分散をよりよく実施するため、アダプタを増設する必要があるかもしれません。

  • ディスクに対し I/O 中心のワークロードがかかっている場合は特に、複数のドライブを、分離した I/O バス上に配置する。
  • ワークロードを複数のドライブ間で分散する - Windows クラスタ化および分散ファイル システムでは、複数のドライブ上での負荷分散のためのソリューションが提供されます。
  • ファイルの圧縮または暗号化の使用を制限する - ファイルの圧縮と暗号化は I/O 中心の処理です。これらの機能は、絶対的に必要なときのみの使用とします。
  • ショート ネーム作成を無効化する - Windows 3.x クライアント用の MS-DOS をサポートしない場合は、ショート ネームを無効化し、パフォーマンスを向上させます。ショート ネームの無効化を行うには、 (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Filesystem 内の) \NtfsDisable8dot3NameCreation レジストリ エントリの規定値を 1 に変更します。
  • 最終アクセスの更新を無効化する - デフォルトでは、NTFS はディレクトリを探索するときは必ず、ディレクトリにある最後のアクセスの日付とタイム スタンプを更新します。NTFS ボリュームが大きいときは、この更新処理によりパフォーマンスが低下することがあります。自動更新を無効化するには、HKEY_LOCAL_MACHINE\SYSTEM \CurrentContolSet\Control\Filesystem 内に NtfsDisableLastAccessUpdate という名称の新規 REG_DWORD レジストリ エントリを作成し、その値を 1 とします。

    メモ: 増分バックアップ ユーティリティなどのアプリケーションの中には、NTFS の更新情報に依存し、それがないときは、仕様上機能を停止するものもあります。


  • マスター ファイル テーブル用に適切なスペースを確保する - HKEY_LOCAL_MACHINE \SYSTEM \CurrentControlSet\Control \FileSystem 内の REG_DWORD として、レジストリに、NtfsMftZoneReservation エントリを追加します。このエントリをレジストリに追加すると、システムは、ボリューム上に、マスター ファイル テーブル用のスペースを確保します。この方法でスペースを確保すると、マスター ファイル テーブルの拡張が最適化されます。NTFS ボリュームの持つ、サイズの大きなファイルの数が比較的少ない場合は、このレジストリ エントリを 1 (規定値) に設定します。中程度のファイル数であれば、通常は、2 あるいは 3 を使い、ボリュームが含むファイル数が相対的に大きいときは、4 (最大値) をセットします。ただし、2 を超える値を使う設定では、システムがマスター ファイル テーブルのためディスク上にかなり大きなスペースを確保してしまうので、必ずテストを実施してください。
  • コントローラ、I/O、ケーブル、ディスクなどについて、もっとも効率の良いディスク システムを使用する- 割り込み調停あるいは割り込み回避をサポートする、インテリジェント ドライバを使って、ディスク I/O によるプロセッサの割り込み処理を軽減します。
  • 適切な RAID 構成を使っているかどうか確認する - 最大のパフォーマンスとフォールト トレランスを得るため、RAID 10 (ストライピング ミラー) を使います。トレードオフは、RAID 10 を使用すると負荷が高くなるということです。規模の大きい書き込み処理がある場合は、RAID 5 (パリティ付きストライピング) を使用しないでください。
  • データベース パーティションの使用を検討する - データベース ボトルネックがある場合は、データベース パーティションを使用することと、ディスクを特定のテーブルおよびトランザクション ログへマッピングすることを検討します。パーティションを使用する主目的は、大きなテーブルについてディスク ボトルネックを解消することにあります。行数が多いテーブルがあり、それがボトルネックの原因と判断できるときは、パーティションの使用を検討します。SQL Server では、ファイル グループを使って I/O パフォーマンスを改善することができます。テーブルをファイル グループに関連付け、そのファイル グループを特定のハード ディスクに関連付けることができます。ファイル グループについての詳細情報は、第 14 章「SQL Server パフォーマンスの向上」を参照してください。
  • ハード ディスク間でファイルを分割することを検討する - 規模の大きなファイル関連処理を行っているときは、複数のハード ディスク間でファイルを分割し、I/O 負荷を複数のディスクに分散させることを検討します。
  • 読み取られる頻度の高い静的データである RAM でのキャッシュの実行可能性を確認する。
  • 過剰なページ フォールトが起きた場合は、メモリの増設を検討する。
  • 高 RPM のディスクの使用あるいはストレージ エリア ネットワーク (SAN) デバイスへの切り替えを検討する。

ネットワーク I/O

ネットワーク I/O は、サーバーのインターフェイス カードによって送受信されているデータの量に関係します。ディスク I/O 関連のボトルネックを生じさせる可能性のある処理には、リモート呼び出し数が多すぎること、各呼び出しで送受信されるデータ量が多すぎること、ネットワーク帯域幅の制約、すべてのデータが単一のネットワーク インターフェイス カード (NIC) を通ることなどがあります。

以下の方法で、ネットワーク I/O ボトルネックを解消します。

  • リモート呼び出し数とネットワークで送信されるデータ量を削減します。帯域幅に関する制約レベルを越えないようにします。
  • コードの最適化が終了している場合は、サーバー上のトラフィックを複数の NIC で分割することが必要かどうかを判断します。使用しているプロトコルをベースとして分割できます。もしくは、別々の NIC を使用することで、分離したネットワーク セグメントと通信が可能です。
  • NIC のアップグレードを検討します。

構成の概要

考えられるボトルネックを示すものがないか、前方インターフェイスと後方インターフェイスの両方を監視します。Windows 2000 におけるネットワーク固有のオブジェクトを監視するには、ネットワーク モニタ ドライバをインストールする必要があります。

ネットワーク モニタ ドライバをインストールするには

  1. コントロール パネルの [ネットワークとダイアルアップ接続] をダブルクリックします。
  2. 接続を選択します。
  3. [ファイル] メニューの [プロパティ] をクリックします。
  4. [全般] タブで、[インストール] をクリックします。
  5. [プロトコル] をクリックし、次に [追加] をクリックします。
  6. [ネットワーク モニタ ドライバ] をクリックし、次に [OK] をクリックします。
  7. [閉じる] をクリックします。

メトリクス

表 17.4 に示すパフォーマンス カウンタを使ってネットワーク I/O ボトルネックを特定できます。

表 17.4: ネットワーク I/O ボトルネックを特定するのに使うパフォーマンス カウンタ

カテゴリカウンタ
Network Interface
(ネットワーク インターフェイス)
Bytes Total/sec
Bytes Received/sec
Bytes Sent/sec
Server Bytes
(サーバー バイト数)
Total/sec
Protocol
(プロトコル)
Protocol_Object\Segments Received/sec
Protocol_Object\Segments Sent/sec
Processor
(プロセッサ)
% Interrupt Time

これらのカウンタの計測方法、しきい値および意味についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「ネットワーク I/O」を参照してください。

ボトルネックの特定

バイト送受信速度が、接続帯域幅もしくはネットワーク アダプタが処理できる帯域幅より高い場合は、ネットワーク帯域幅のボトルネックが生じています。この速度は、Network Interface\Bytes Total/sec で計測します。

チューニング オプション

ネットワーク I/O がボトルネックであると判断した場合は、以下の選択肢があります。

  • 複数のネットワーク アダプタ間でクライアント接続を分散させる - システムが、トークン リング、光ファイバー分散データ インターフェイス (FDDI)、またはスイッチド イーサネット ネットワークを使って通信を行っている場合は、クライアント接続を複数のネットワーク アダプタ間で分散させて、ネットワーク トラフィックのバランスを取るようにします。複数のネットワーク アダプタを使うときは、ネットワーク アダプタが、PCI のバス間で分散されるようにします。たとえば、ネットワーク アダプタ 4 個と PCI バス 3 個 (64 ビットが 1 個、32 ビットが 2 個) の場合、2 個のネットワーク アダプタを 64 ビットのバスに、残り 2 個のアダプタを 32-ビットのバスにそれぞれ割り当てます。
  • 最高のパフォーマンスを得るために、アダプタを使用可能な最大帯域幅で使用する - 帯域幅を広げると、発生する送信数が増大します。これは、つまり、割り込みなどのシステムが実行すべき作業も増大するということです。使用していないネットワーク アダプタを外し、オーバーヘッドを削減します。
  • チェックサム オフローディング、IPSec オフローディング、大量送信オフローディングなどのタスク オフロード機能をサポートするアダプタを使う。
  • 割り込み調停を使って、割り込みをバッチ処理するネットワーク アダプタを使う - ネットワーク アダプタからの割り込みが高い率で行われると、パフォーマンスが低下します。割り込み調停を使って割り込みをバッチ処理するネットワーク アダプタを使うことで、アダプタ ドライバがこの機能に対応していれば、このようなパフォーマンス問題を緩和することができます。もうひとつの選択肢として、ネットワーク アダプタで生じる割り込みを特定のプロセッサにバインドすることもできます。
  • ネットワークが複数のプロトコルを使用している場合は、各プロトコルを別々のアダプタに割り当てる - もっとも効率の良いプロトコル、特にブロードキャストを最小限にするプロトコルを使用してください。
  • ネットワークを複数のサブネットまたはセグメントに分割し、別々のアダプタを使ってサーバーを各セグメントに割り当てます。そうすることで、サーバー要求が分散され、サーバー上の混雑状態が軽減されます。

.NET Framework のチューニング

.NET Framework をチューニングするには、CLR をチューニングすることが必要です。CLR のチューニングは、実装テクノロジにかかわらず、すべてのマネージ コードに影響を及ぼします。該当する .NET Framework テクノロジのチューニングは、アプリケーションの特性を考慮して実施します。たとえば、該当するテクノロジのチューニングには、ASP.NET アプリケーションあるいは Web サービス、Enterprise Services および ADO.NET のコードについてのチューニングが含まれます。

CLR のチューニング

CLR のチューニングは、CLR がタスクを効率よく実行できるように、コードを設計し、最適化することによってほぼ達成されます。設計時は、オブジェクトのライフタイムを考慮し、Dispose パターンを適切に使うというような方法で、効率の良いガベージ コレクションを必要とします。

CLR に関連する主要ボトルネックは、リソースのための競合、効率の悪いリソース クリーンアップ、スレッド プールの誤用、リソース リークなどによって発生します。効率的な CLR 処理のためのコードの最適化についての詳細情報は、第 5 章「マネージ コード パフォーマンスの向上」を参照してください。

メトリクス

表 17.5 に示すパフォーマンス カウンタを使って、CLR ボトルネックを特定できます。

表 17.5: CLR ボトルネックを特定するのに使うパフォーマンス カウンタ

カテゴリカウンタ
Memory (メモリ)Process\Private Bytes
.NET CLR Memory\% Time in GC
.NET CLR Memory\# Bytes in all Heaps
.NET CLR Memory\# Gen 0 Collections
.NET CLR Memory\# Gen 1 Collections
.NET CLR Memory\# Gen 2 Collections
.NET CLR Memory\# of Pinned Objects
.NET CLR Memory\Large Object Heap size
Working Set
(ワーキング セット)
Process\Working Set
Exceptions (例外).NET CLR Exceptions\# of Exceps Thrown /sec
Contention (競合).NET CLR LocksAndThreads\Contention Rate / sec
.NET CLR LocksAndThreads\Current Queue Length
Threading
(スレッド処理)
.NET CLR LocksAndThreads\# of current physical Threads
Thread\% Processor Time
Thread\Context Switches/sec
Thread\Thread State
Code Access Security
(コード アクセス セキュリティ)
.NET CLR Security\Total Runtime Checks
.NET CLR Security\Stack Walk Depth

これらのカウンタの計測方法、しきい値および意味についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「ASP.NET」を参照してください。

ボトルネック

以下のリストは、マネージ コードを使って作成されたアプリケーションで発生する代表的なボトルネックと、システム カウンタを使ってこのようなボトルネックを特定する方法を説明します。計測対象と計測方法についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「CLR とマネージ コード」を参照してください。

  • 過剰なメモリ消費 - 過剰なメモリ消費は、マネージ あるいはアンマネージ メモリの管理がうまくいっていないときに発生する可能性があります。この兆候を特定するには、以下のパフォーマンス カウンタを観察します。
    • Process\Private Bytes
    • .NET CLR Memory\# Bytes in all Heaps
    • Process\Working Set
    • .NET CLR Memory\Large Object Heap size

    # of Bytes in all Heaps 値が変化せず、Private Bytes 値が増加する場合は、アンマネージ メモリが消費されていることを示します。両方の値が増加する場合は、マネージ メモリが消費されていることを示します。

  • サイズの大きなワーキング セット - ワーキング セットとは、現在 RAM にロードされている一組のメモリ ページです。これは Process\Working Set によって計測されます。値が大きい場合は、多数のアセンブリがロードされていることを示します。他のカウンタとは異なり、Process\Working Set には、注意すべき固有のしきい値はありませんが、値が大きい場合、あるいは変動する場合は、メモリ不足を示している場合があります。このような値のときは、ページ フォールトが発生することが多く、これは、サーバーがメモリ不足に陥っていることを明確に示すものです。
  • サイズの大きなオブジェクト ヒープの断片化 - サイズが 83 KB を超えるオブジェクトは、.NET CLR Memory\Large Object Heap size で計測されるサイズの大きなオブジェクト ヒープ内に割り当てられます。多くの場合、このようなオブジェクトは、I/O 処理 (たとえば、アップロードされた画像を読み取るための BinaryReader の作成) に使われるバッファ (サイズの大きな文字列、バイト配列など) です。このような大規模な割り当てでは、サイズの大きなオブジェクト ヒープの断片化を生じさせることがあります。断片化を回避するため、このようなバッファのリサイクルを検討してください。
  • 高い CPU 使用率 - 高い CPU 使用率は、通常は、マネージ コードが適切に作成されていないために発生します。以下のようなコードが原因となります。
    • 過剰なガベージ コレクションを引き起こすコード。% Time in GC で計測できます。
    • 大量の例外をスローするコード。.NET CLR Exceptions\# of Exceps Thrown /secGC で計測できます。
    • 大量のスレッドを作成するコード。このようなコードにより、CPU は、必要な作業ではなくスレッド間の切り替えに長時間を費やすことになってしまいます。これは、Thread\Context Switches/sec で計測できます。
  • スレッドの競合 - 複数のスレッドが共有リソースにアクセスしようとするとスレッドの競合が発生します。この兆候を特定するには、以下のパフォーマンス カウンタを観察します。

    .NET CLR LocksAndThreads\Contention Rate / sec

    .NET CLR LocksAndThreads\Total # of Contentions

    高い競合率あるいは合計競合数の著しい増大は、アプリケーションがスレッドの競合に遭遇していることを明確に示しています。この問題を解決するには、共有リソースにアクセスしている、あるいは同期メカニズムを使っているコードを特定してください。

ASP.NET のチューニング

ASP.NET のチューニングに着手するときは、以下を考慮してください。

  • クライアントと ASP.NET とのやり取り - 考慮すべき事項としては、キューのサイズ、タイムアウト (実行タイムアウト、プロキシのタイムアウト、デッドロック間隔、セッション タイムアウト)、サイズの大きなファイルのアップロードとダウンロード、要求と応答のサイズがあります。
  • ワーカー プロセス - 考慮すべき事項としては、メモリの割り当て量、ビュー ステートとセッション ステートのサイズ、キャッシュのサイズ、CPU 使用率、スレッド アフィニティがあります。スレッド アフィニティが回避できない場合は、Web ガーデンを考慮する必要があります。
  • ASP.NET からの、リモートあるいはローカルの Web サービス呼び出し - 考慮すべき事項には、接続数とスレッド プールの使用率が含まれます。

ASP.NET のチューニングについては、設計やコードといった観点から離れた上記のカテゴリを最適化することから始め、その次に個々のカテゴリに対してチューニングを実行するという方法をとります。

構成の概要

ほとんどの ASP.NET チューニングは、システム全体の Machine.config ファイルおよびアプリケーション固有の Web.config ファイルにある構成パラメータを修正することで、実行されます。図 17.10 に、ASP.NET のアーキテクチャと、ASP.NET と Machine.config にある主要構成要素との関係を示します。

主要構成要素と要求処理サイクルのマッピング

図 17.10: 主要構成要素と要求処理サイクルのマッピング

ASP.NET アプリケーションのチューニングについては、多数の選択肢があり、その多くは、Machine.config の設定についてのチューニングを必要とします。この構成ファイルには、多くのセクションがありますが、パフォーマンスについては、以下のセクションがもっとも重要です。

<processModel>

<processModel> 要素の属性は、ASP.NET のワーカー プロセス (aspnet_wp.exe) と、IIS 5 Web サーバー上でこのワーカー プロセスがホストするすべてのアプリケーションに適用されます。設定項目の多くは、規定値にチューニングされており、変更は不要です。規定値は以下のとおりです。

<processModel enable="true" timeout="Infinite" idleTimeout="Infinite"
shutdownTimeout="0:00:05" requestLimit="Infinite"
requestQueueLimit="5000" restartQueueLimit="10" memoryLimit="60"
webGarden="false" cpuMask="0xffffffff" userName="machine"
password="AutoGenerate" logLevel="Errors"
clientConnectedCheck="0:00:05" comAuthenticationLevel="Connect"
comImpersonationLevel="Impersonate"
responseDeadlockInterval="00:03:00" maxWorkerThreads="20"
maxIoThreads="20"/>

各属性についての詳細説明は、.NET Framework 一般情報リファレンスの「<processModel> 要素」 ( http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpgenref/html/gngrfprocessmodelsection.asp ) を参照してください。

<httpRuntime>

<httpRuntime> 要素は、ASP.NET ランタイム設定値を構成するものです。コンピュータ、サイト、アプリケーション、サブディレクトリの各レベルで設定を行うことができます。Machine.config ファイルの規定値は以下のとおりです。

<httpRuntime executionTimeout="90" maxRequestLength="4096"
useFullyQualifiedRedirectUrl="false" minFreeThreads="8"
minLocalRequestFreeThreads="4" appRequestQueueLimit="100"
enableVersionHeader="true"/>

各属性についての詳細説明は、.NET Framework 一般情報リファレンスの「<httpRuntime> 要素」 ( http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpgenref/html/gngrfhttpruntimesection.asp ) を参照してください。

スレッド プール属性

図 17.11 に、コンテキストにおける、ASP.NET のスレッド プールの構成オプションを示します。

ASP.NET のスレッド プールの構成オプション

図 17.11: ASP.NET のスレッド プールの構成オプション

以下のリストで、ASP.NET のスレッド プールに関して、machine.config ファイルの (<processModel> および <httpRuntime> 内にある) 主要属性を説明します。

また、各属性が適用されるシナリオについても説明します。

  • maxconnection - アプリケーションがリモートの Web サービスに対して呼び出しを行い、要求がその呼び出しの完了を待機している場合、Machine.config ファイルの <ConnectionManagement> 要素にある maxconnection 属性を変更して、CPU 使用率とアプリケーションのパフォーマンスを上げることができます。規定値は以下のとおりです。
    <connectionManagement>
    <add address="*" maxconnection="2"/>
    
    </connectionManagement>
    

    maxconnection の値を大きくすることで、より多くのリモートの Web サービスに対する呼び出しを並行して実行できます。この属性は、ローカルの Web サービスへの呼び出しには影響を及ぼしません。同時呼び出し数を増やすと、リモート呼び出しに使用するスレッドの使用率も上がります。

    maxconnection の値を大きくすると、CPU 使用率も上がる可能性があります。CPU 使用率の上昇は、ASP.NET が、多数の受信要求が Web サービス呼び出すまで待機させずに、その受信要求を処理するために起こります。maxconnection 属性と、ここで説明する他の属性および実際の CPU 使用率とのバランスを取る必要があります。

  • maxWorkerThreads と maxIoThreads - ASP.NET のワーカー プロセスが作成を許可されているワーカー スレッドと I/O スレッドの最大数を定義する属性です。これらの値は、ワーカー プロセスが実際に作成するスレッド数には影響を及ぼすことはありません。最大値は、1 台のプロセッサにつき 100 です。

    前述したように、maxconnection 値を大きくすると、並列処理数が増え、より多くのワーカー スレッドと I/O スレッドが必要となります。これらの属性をチューニングするときは、以下のガイドラインを考慮してください。

    • これらの属性を変更するのは、プロセッサの使用率が、アプリケーションのパフォーマンス目標で定義した限界値を下回っているときのみとします。
    • 要求が I/O 呼び出しについて待機しているわけではないものの、実際には CPU に負荷のかかる作業を実行しているときは、これらの属性の値を大きくしないでください。このような状況でこれらの属性の値を大きくすると、プロセッサはすでにストレスのかかっているにもかかわらず、さらに処理すべきスレッドのコンテキスト切り替えが増大するため、パフォーマンスに悪影響が及びます。
    • アプリケーションが、所要時間の短い (たとえば、リモートの Web サービスに対する) I/O 呼び出しを行っている場合は、呼び出しスレッドは長時間ブロックされることはないので、これらの値を大きくする必要はないでしょう。
    • アプリケーションが所要時間の長い I/O 呼び出しを行っていて、システムにアイドルとなっている CPU が存在する場合は、これらの属性およびこのセクションで説明する他の関連属性の値を大きくすることを検討しても問題はありません。システムにアイドルとなっている CPU がない場合は、これらの属性の値を大きくするべきではありません。

    Web アプリケーションのあるサーバー上に Web サービスも存在する場合は、以下を考慮して、いつ規定値より大きい値を設定すべきかを判断します。

    • これらの属性の値を大きくするのは、プロセッサの使用率が、アプリケーションのパフォーマンス目標で定義した限界値を下回っているときのみとします。
    • 要求が I/O 呼び出しについて待機しているわけではないものの、実際には CPU に負荷のかかる作業を実行しているときは、これらの属性の値を大きくしないでください。このような状況でこれらの属性の値を大きくすると、プロセッサはすでにストレスのかかっているにもかかわらず、さらに処理すべきスレッドのコンテキスト切り替えが増大するため、パフォーマンスに悪影響が及びます。
    • maxconnection と minFreeThreads - ローカルな Web サービス呼び出しのみを行っていシナリオにでは、これらの属性が与える影響はありません。
  • minFreeThreads - ワーカー プロセスに対して送信されてくる要求を処理する以外の作業に使用できるスレッドの数を定義する属性です。この属性により、フリー スレッドのカウントが限界値を下回っていることが示されているときは、ASP.NET のプロセスは、新規の HTTP 要求を処理するのにスレッド プールからのスレッドを使用できません。この属性は、<httpRuntime> 要素で指定されるもので、規定値は 8 となっています。

    この属性を使えば、保留中の非同期要求からのコールバックを処理するのに使えるスレッドを確保できるので、デッドロックを防ぐことができます。デッドロックは、受信 HTTP 要求を処理するのにスレッド プール内のすべてのスレッドが使用されていて、1 つ以上の要求が非同期コールバックを待機しているときに、発生する可能性があります。この状況では、コールバックを処理するスレッドがありません。このコールバック処理に使えるフリー スレッドを確保するのに、minFreeThreads を設定することができます。

    minFreeThreads の値を大きくするということは、リモート呼び出し用に、より多くのスレッドを確保するということです。いかなる場合でも、maxWorkerThreads - minFreeThreads ≧ 12 となるようにします。12 は、ASP.NET のワーカー プロセスが要求を処理するのに使用できるスレッドの最適数です。この値は、ASP.NET が 13 以上の要求を同時には実行できないということを意味します。この限界値は、ワーカー プロセスが、通常はこれらのスレッドのうち 4 つのスレッドを使うことを示す、一連のパフォーマンス テストから導き出したものです。プロセッサが全面的に使用され (使用率が 95% を超える)、アプリケーションが所要時間の長い呼び出しを行う場合、ワーカー プロセスは、12 個すべてのスレッドを使用する可能性があります。

    以下のようなシナリオでは、この属性の値を、規定値より大きくすると良いでしょう。

    • maxWorkerThreads および maxIoThreads の値を大きくしてある。
    • より多くのバックエンド呼び出しを処理するため、maxconnection の値を大きくしてあり、またそのため、より多くのスレッドを使用可能な状態にしておく必要がある。
    • 実行をブロックするような、所要時間の長い呼び出しを行うときは、この属性値の変更を検討する必要があるかもしれません。変更を加えた場合、サーバーにとっては、作業がコンピュータに高い負荷をかけないものであれば、属性値の変更のメリットは非常に大きいものとなります。
  • minLocalRequestFreeThreads - 同一のコンピュータ上にある Web サービス を使う Web アプリケーションについては、ローカル呼び出しの処理を優先することが必要なときは、minLocalRequestFreeThreads の値を小さくすることを検討します。この属性は、ローカルホストからの要求をキューに入れないようにするため、ASP.NET が使用可能にしておくフリー スレッドの最小数を定義します。ローカル要求を処理する前に、ランタイムが、少なくともこの最小数のワーカー スレッドが使用可能になっているかどうかを確認します。使用できるスレッドの数がこの最小数よりも少ない場合、要求はキューに入れられます。

    規定値は 4 となっているので、3 つのワーカー スレッドだけが使用可能な場合は、ローカル要求はキューに入れられます。この値を小さくすると、ASP.NET は、ますますスレッドを使うようになるので、ローカル キューイングは少なくなります。

    メモ: スレッド プール内のフリー スレッド数が minFreeThreads の値を下回ると、リモート クライアントからの要求についてのキューイングが開始します。

    minFreeThreads 属性を変更せずに minLocalRequestFreeThreads の値を小さくすると、ワーカー プロセスに対し、ローカル サーバーからの呼び出しを終了することを最優先するように指示していることになります。

メトリクス

表 17.6 に示すパフォーマンス カウンタを使って ASP.NET ボトルネックを特定できます。

表 17.6: ASP.NET ボトルネックを特定するのに使うパフォーマンス カウンタ

カテゴリカウンタ
Worker Process
(ワーカー プロセス)
ASP.NET\Worker Process Restarts
Throughput (スループット)ASP.NET Applications\Requests/Sec
Web Service\ISAPI Extension Requests/sec
Requests: ASP.NET\ Requests Current
ASP.NET Applications\Requests Executing
ASP.NET Applications\ Requests Timed Out
Response time / latency
(応答時間 / 待ち時間)
ASP.NET\ Request Execution Time
Cache (キャッシュ) ASP.NET Applications\ Cache Total Entries
ASP.NET Applications\ Cache Total Hit Ratio
ASP.NET Applications\Cache Total Turnover Rate
ASP.NET Applications\Cache API Hit Ratio
ASP.NET Applications\ Cache API Turnover Rate
ASP.NET Applications\ Output Cache Entries
ASP.NET Applications\ Output Cache Hit Ratio
ASP.NET Applications\ Output Cache Turnover Rate

これらのカウンタの計測方法、しきい値および意味についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「ASP.NET」を参照してください。

ボトルネック

以下のリストで、ASP.NET アプリケーションで発生する一般的なボトルネックと、表 17.6 のシステム カウンタを使って、それらのボトルネックを特定する方法を説明します。計測対象と計測方法についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「ASP.NET」を参照してください。

  • スレッド プールの枯渇 - ASP.NET において、受信する要求の処理や I/O 作業の実行を行うワーカー スレッドと I/O スレッドが不足すると、スレッド プールに関するボトルネックが発生する可能性があります。

    この状態を特定するには、以下のパフォーマンス カウンタに注意してください。

    • ASP.NET\Requests Queued
    • Process\% Processor Time (aspnet_wp.exe あるいは w3wp.exe)

    プロセッサ使用率が低い状態にもかかわらず、要求がキューに入れられている場合は、ASP.NET が 非 CPU 依存の作業を実行しているという可能性が濃厚です。アプリケーションが、リモートあるいはローカルの Web サービスに対して呼び出しを行っている場合は、スレッド プールをチューニングして、この問題を解決できます。スレッド プールのチューニング方法についての詳細情報は、第 6 章「ASP.NET パフォーマンスの向上」の「スレッド処理についての説明」を参照してください。

    代替案として、独自のパフォーマンス カウンタを使ってスレッド プールを監視し、使用可能な I/O スレッドとワーカー スレッドについて詳細な調査をすることもできます。詳細情報については、このガイドの「How To 情報」にある「カスタム カウンタを使った、ASP.NET スレッド プールの監視方法」を参照してください。

  • スレッドの競合 - この章の前半にある「CLR のチューニング」の「ボトルネック」で説明したように、複数のスレッドがひとつの共有リソースにアクセスしようとすると、スレッドの競合が発生します。
  • メモリ上のボトルネック - メモリに関するボトルネックには、さまざまな形態があります。原因としては、メモリ リーク、断片化、効率の悪いリソースのクリーンアップ、あるいは単純にワーカー プロセスに対して割り当てたメモリ量が多すぎるまたは少なすぎるといったことがあります。このような兆候を特定するには、この章の「メモリ」で説明した、システム レベルのメモリに関するカウンタに加えて、以下のパフォーマンス カウンタを観察します。
    • Process\Private Bytes (aspnet_wp.exe あるいは w3wp.exe)
    • Process\Virtual Bytes (aspnet_wp.exe あるいは w3wp.exe)
    • .NET CLR Memory\# Bytes in all Heaps (aspnet_wp.exe あるいは w3wp.exe)

    いずれかのカウンタが増加し続けていて、一定の値にならない場合、アプリケーションにはメモリ リークが起きています。# Bytes in all HeapsPrivate Bytes が増加し続けている場合は、アプリケーションに、マネージ メモリのリークが発生しています。Private Bytes カウンタだけが増加している場合は、アプリケーションに、ネイティブ メモリのリークが生じています。

    Private BytesVirtual Bytes の差がしだいに大きくなっていく場合は、ディスクの断片化が原因となっていることがあります。アプリケーションが OutOfMemoryException をスローしている場合も、メモリがボトルネックになっていることを示します。

    Machine.config ファイル内の <processModel> 要素にある memoryLimit 属性を設定することで、ASP.NET のワーカー プロセスに割り当てるメモリ量を構成することが可能です。

    Machine.config ファイルの <processModel> 要素にある memoryLimit 属性をチューニングすることで、メモリ ボトルネックを解消できるケースもあります。ただし、この方法でもボトルネックが緩和されない場合は、この問題のトラブルシューティングをさらに進める必要があります。

  • ワーカー プロセスのリスタート - ASP .NET のワーカー プロセスのリスタートは、時間がかかるだけではなく、リソースも消費します。リスタートのしきい値を適切な値に設定し、不要なリスタートを回避します。以下の要素がリサイクルの原因となることがあります。
    • 構成ファイルへの変更。(この変更はアプリケーション ログには記録されません。)
    • デッドロック。
    • メモリ限界値を超過する (<processModel memoryLimit= />)。
    • Machine.config ファイルで指定される、要求とタイムアウトの限界値。

チューニング オプション

以下のチューニング選択肢を考慮します。

  • 競合を削減するための方策を用いてスレッド プールをチューニングする。
  • メモリ制限を設定する。
  • 積極的にタイムアウトを設定する。
  • RequestQueueLimit を設定する。
  • トレースとデバッグを無効にする。
  • セッション状態を使用しないときは無効にする。
  • 必要なければビュー ステートを無効にする。
  • サイズの大きなファイルをアップロードするときは maxRequestLength を考慮する。
  • プロセッサ アフィニティがメリットとなるシナリオでは Web ガーデンを考慮する。

競合を削減するための方策を用いてスレッド プールをチューニングする

競合を減らすための方策は、ASP.NET スレッド プールのチューニングを始めるための、経験に基づいた適切な手法を提供するものです。利用可能な CPU があり、アプリケーションが (Web メソッドの呼び出しやファイル システムへのアクセスなどの) I/O 依存の処理を実行していて、かつ (ASP.NET Applications\Requests In Application Queue で示されるように) 要求をキューに入れているような場合は、表 17.7 に示す Microsoft 製品グループの推奨設定を用いることを検討してください。個々の設定についての詳細情報は、第 6 章「ASP.NET パフォーマンスの向上」の「競合を減らすための方策を用いてスレッド プールをチューニングする」を参照してください。

表 17.7: 競合削減のための推奨スレッド処理設定

構成設定規定値 (.NET 1.1)推奨値
maxconnection212 * CPU数
maxIoThreads20100
maxWorkerThreads20100
minFreeThreads888 * CPU数
minLocalRequestFreeThreads476 * #CPUs

競合を削減するため、Machine.config ファイルの以下の項目を設定する必要があります。このリストに記載する変更は、すべての設定に適用するものであり、単独で行うものではありません。

  • maxconnection を 12 * CPU 数に設定する - クライアント (ここでは ASP.NET) が許可する 送信 HTTP 接続数の最大数を制御する設定です。推奨設定は maxconnection を 12 * CPU 数に設定することです。
  • maxIoThreads を 100 に設定する - CLR スレッド プールにおける I/O スレッドの最大数を制御する設定です。この数値に対し、自動的に、ワーカー プロセッサが、CPU 数をかけます。推奨設定は、maxIoThreads を 100 に設定することです。
  • maxWorkerThreads を 100 に設定する - CLR スレッド プールにおけるワーカー スレッドの最大数を制御する設定です。この値に対し、自動的に、ワーカー プロセッサが、CPU 数をかけます。推奨設定は、maxWorkerThreads を 100 に設定することです。
  • minFreeThreads を 88 * CPU 数 に設定する - スレッド プールにおける利用可能なスレッドの数がこの設定値を下回った場合に、ワーカー プロセスが、すべての受信要求をキューに入れるのに使用する設定です。この設定により、同時実行する要求数を maxWorkerThreads - minFreeThreads に効果的に制限できます。推奨設定は、minFreeThreads を 88 * CPU 数に設定することです。この設定値により、(maxWorkerThreads が 100 に設定されるものとして) 同時要求数は 12 に制限されます。
  • minLocalRequestFreeThreads を 76 * CPU 数に設定する - スレッド プールに内の利用可能なスレッドの数がこの値を下回った際に、ワーカー プロセスが、ローカルホスト (たとえば、要求を同一のコンピュータ上にある Web サービスに送信する Web アプリケーション) からの要求をキューに入れるのに使う設定です。この設定は、 minFreeThreads に似ていますが、ローカル サーバーからの要求のみに適用されます。推奨設定は、set minLocalRequestFreeThreads を 76 * CPU 数に設定することです。

    メモ: 上記の推奨事項は、変えてはいけないというものではなく、あくまでも最初に試すための数値です。適切なテストを実施して、シナリオに適合した設定を見つけてください。


バースト負荷があるシナリオについてはスレッド プールをチューニングする

アプリケーションが (たとえば、1000 クライアントがすべて午前 9 時にログインするというような) 小規模のバースト転送において異常に高いユーザー負荷がかかる場合、システムはこのバースト負荷を処理できなくなる可能性があります。minWorkerThreads および minIOThreads を、Microsoft サポート技術情報の Knowledge Base の文書 810259 「FIX: SetMinThreads と GetMinThreads API を共通言語ランタイム ThreadPool クラスに追加しました」 ( http://support.microsoft.com/default.aspx?scid=kb;ja;810259 ) の指定にしたがって設定することを検討します。

COM オブジェクト呼び出し時にスレッドプールをチューニングする

シングル スレッド アパートメント (STA) の COM オブジェクトを呼び出す ASP.NET の Web ページは、ASPCOMPAT 属性を使います。この属性を使うことで、確実に STA スレッド プールからのスレッドを使って呼び出しが実行されます。ただし、異なる COM オブジェクトへの呼び出しもすべて同一のスレッド上で実行されるため、高負荷のかかる期間中は、このプロセスのスレッド カウントが増大する可能性があります。Process:Thread Count (aspnet_wp インスタンス) パフォーマンス カウンタを確認することによって、ASP.NET のワーカー プロセス内で使われるアクティブ スレッドの数を監視することが可能です。

ASPCOMPAT 属性を使用しているときのスレッド カウントは、使用していないときと比較すると、アプリケーションにとっては高い値になります。アプリケーションが広範囲にわたって STA COM コンポーネントと ASPCOMPAT 属性を使用するシナリオでは、スレッド プールのチューニング時に、ワーカー プロセスのトータル スレッド カウントが以下の値を超えないようにしなければなりません。

75 + ((maxWorkerThread + maxIoThreads) * #CPUs * 2)

変更を評価する

競合削減のための方策が機能したかどうかを判定するには、スループットが向上したかどうかを確認してください。特に、以下の改善がみられたかどうかを確認します。

  • CPU 使用率が増加している。
  • ASP.NET Applications\Requests/Sec パフォーマンス カウンタと比例して、スループットが増大している。
  • ASP.NET Applications\Requests In Application Queue パフォーマンス カウンタと比例して、アプリケーションのキューに入れられた要求が減少している。

この変更でシナリオが改善されていない場合は、CPU 依存のシナリオとなっている可能性があります。CPU 依存のシナリオでは、スレッドを増やすと、スレッドのコンテキスト切り替えを増加させ、さらにパフォーマンスを低下させてしまいます。

スレッド プールのチューニング時は、Process\Thread Count (aspnet_wp) パフォーマンス カウンタを監視します。この値は、以下の値を超えてはなりません。

75 + ((maxWorkerThread + maxIoThreads) * #CPUs)

AspCompat を使用している場合は、以下の値を超えてはなりません。

75 + ((maxWorkerThread + maxIoThreads) * #CPUs * 2)

この最大値を超えると、プロセッサのコンテキスト切り替えが増加してしまいます。

詳細情報

詳細情報については、以下の資料を参照してください。

  • “ASP.NET Performance Monitoring, and When to Alert Administrators” (著者: Thomas Marquardt、http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/monitor_perf.asp)
  • Web サービスのシナリオについての詳細情報は、Microsoft サポート技術情報の Knowledge Base の文書 821268 「[PRB] ASP.NET アプリケーションから Web サービス要求を行うと、競合、パフォーマンスの低下、およびデッドロックが発生する」 ( http://support.microsoft.com/default.aspx?scid=kb;ja;821268 ) を参照してください。
  • “At Your Service: Performance Considerations for Making Web Service Calls from ASPX Pages” (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service07222003.asp)
  • Microsoft Support WebCast “Microsoft ASP.NET Threading” (http://support.microsoft.com/default.aspx?scid=%2fservicedesks%2fwebcasts%2fen%2ftranscripts%2fwct060503.asp)
  • Microsoft サポート技術情報の Knowledge Base の文書 827419 「新しい GetMinThreads メソッドと .NET FRAMEWORK 1.1 の ThreadPool クラスの新しい SetMinThreads メソッドの情報」 ( http://support.microsoft.com/default.aspx?scid=kb;ja;827419 )
  • Microsoft サポート技術情報の Knowledge Base の文書 810259 「FIX: SetMinThreads と GetMinThreads API を共通言語ランタイム ThreadPool クラスに追加しました。」 ( http://support.microsoft.com/default.aspx?scid=kb;ja;810259 )

メモリ制限を設定する

ASP.NET におけるメモリのしきい値は、Machine.config ファイル内の <processModel> 要素にある、memoryLimit 属性によって次のように決定されます。

<processModel ... memoryLimit="60" .../>

この値は、プロセスが消費することを許可された物理メモリのパーセンテージを制御します。この値を超えると、ワーカー プロセスはリサイクルされます。コード内に示された規定値は、サーバーにインストールされた全物理メモリの 60 パーセントを表しています。

この設定値は、ASP.NET におけるキャッシュのスカベンジング メカニズムと仮想メモリのページ処理に影響を及ぼすため、重要です。詳細情報については、第 6 章「ASP.NET パフォーマンスの向上」の「メモリ制限を設定する」を参照してください。規定値は、ページ処理を最小限に抑えるよう最適化されています。(Memory\Pages/sec パフォーマンス カウンタを監視することによって) ページ処理が活発に行われているのに気づいたら、システムに十分な物理メモリがあれば、既定制限値を大きくすることができます。

推奨するチューニング手法は、システム モニタにおけるページ処理とともに、Process\Private Bytes (aspnet_wp) パフォーマンス カウンタの計測によって、ASP.NET ワーカー プロセスが消費する全メモリを計測することです。カウンタにより、メモリ消費がこのプロセスの規定制限値に近づいていることが示されている場合は、アプリケーションにおいて効率の悪いクリーンアップが生じた恐れがあります。メモリが効率的にクリーンアップされているにもかかわらず、制限値を大きくする必要がある場合、そうするのは十分な物理メモリがあるときのみとしてください。

サーバーに 4 GB 以上の RAM があるときは、この制限値を調整することが重要です。メモリ制限の規定値が 60 パーセントということは、ワーカー プロセスに 2.4 GB の RAM が割り当てられているということであり、これはプロセス用仮想アドレス空間の規定値 (2 GB) よりも大きいものです。この差異が、OutOfMemoryException を生じさせる可能性を増大させます。

IIS 5 Web サーバー上で、このような状況を回避するため、.NET Framework 1.0 については、この制限値を 800 MB あるいは物理 RAM の 60 パーセントまで小さくしてください。

/3GB スイッチ

.NET Framework 1.1 は、3 GB の仮想空間をサポートしています。boot.ini に /3GB スイッチを追加すると、メモリ制限の上限として 1,800 MB を安全に使用することができます。

/3GB スイッチは、以下のオペレーティング システムで使用してください。

  • Microsoft Windows Server(TM) 2003
  • Microsoft Windows 2000 Advanced Server
  • Microsoft Windows 2000 Datacenter Server
  • Microsoft Windows NT 4.0 Enterprise Server

以下のオペレーティング システムでは、/3GB スイッチを使用しないでください。

  • Microsoft Windows 2000 Server
  • Microsoft Windows NT 4.0 Server

Windows 2000 Server および Windows NT 4.0 Server が、ユーザー モード プログラムに割り当てるのは 2 GB だけです。Windows 2000 Server または Windows NT 4.0 Server で /3GB スイッチを使うと、カーネルに 1 GB、ユーザー モード プログラムに 2 GB が割り当てられ、アドレス空間の 1 GB を失うことになってしまいます。

IIS 6

IIS 6 については、Recycling ページ上のインターネット サービス マネージャ内の Maximum used memory [最大使用メモリ] (メガバイト単位) の設定を使って、ワーカー プロセスが使用を許可された最大メモリを設定します。図 17.12 で示すように、値はメガバイト単位であり、物理 RAM のパーセンテージを示すものではありません。

IIS 6 マネージャにおけるメモリのリサイクル設定

図 17.12: IIS 6 マネージャにおけるメモリのリサイクル設定

詳細情報

詳細情報については、以下の資料を参照してください。

積極的にタイムアウトを設定する

以下のリストで、タイムアウトに関するチューニングが可能な構成設定を説明します。

  • executionTimeout - <httpRuntime> 要素にある属性で、規定値は 90 秒となっています。以下のように HttpServerUtility.ScriptTimeout を使って、この属性をプログラム的に設定できます。
    <httpRuntime executionTimeout="90" />
    

    アプリケーションが、サイズの大きなファイルの転送や、所要時間の長い呼び出しなど 90 秒を超えるような、所要時間の長い処理を実行する場合は、規定値を変更する必要があります。この属性の値を変更する場合は、以下のガイドラインを考慮します。

    • 平均的な Web アプリケーションのクライアントの期待する応答時間は 7 ~ 10 秒です。所要時間の長すぎる要求を意図的にタイムアウトし、ユーザーに対しエラー メッセージを表示するため、executionTimeout の値を小さくすることを検討します。
    • executionTimeout の値を大きくするという判断は慎重に行ってください。極めて大きなサイズのファイルを転送するようなシナリオでは、この属性の値を大きくするのが正しい方法と言えるかもしれません。それでも、ユーザー インターフェイスの反応に関する問題を念頭に置き、ユーザーがそれだけの長時間、応答を待ってくれるかどうかを考慮することが必要です。

      タイムアウト時間を長くすると、サーバーのリソースが長時間保持されるため、サーバーには高負荷がかかったままストレスが生じ、不安定な状態になる可能性があります。

      executionTimeout の値を 180 秒より長くすることが本当に必要なシナリオでは、responseDeadlockInterval 属性の値を 180 秒 (規定値) よりも大きくする必要があります。

      さらに、executionTimeout の値を Web サービスのプロキシ上でクライアントが設定したタイムアウト値よりも大きくする必要があります。Web ページについての要求が、そのページから Web サービスに呼び出しが発行される前にタイムアウトしてしまうと、ソケット接続がオープンになり、リソース リークが生じる恐れがあります。

      Web サービスを呼び出す ASP.NET ページは、プロキシ オブジェクト上の TimeOut のプロパティを設定できます。このタイムアウト値は、executionTimeout の値より小さく、また、executionTimeout は、responseDeadlockInterval の値より小さいものでなければなりません。ASP.NET ページをホストするサーバー上の executionTimeout の値は、Web サービスをホストするサーバー上の executionTimeout より大きくする必要があります。この設定により、所要時間の長い Web サービスは正常終了しますが、ASP.NET ページは ThreadAbortException を返します。


      メモ: タイムアウト値は、ミリ秒単位で指定されます。Web.config ファイルにおいて debug="true" となっている場合は、executionTimeout の値は無視されます。


      Web サービスのプロキシについて、タイムアウトをチューニングする手法についての詳細情報は、第 10 章「Web サービス パフォーマンスの向上」の「タイムアウト」を参照してください。

  • responseDeadlockInterval - 以下のように、ASP.NET が、サーバー上のデッドロックあるいはスレッドの競合を検出するのに使う属性です。
    <processModel responseDeadlockInterval="00:03:00" />
    

    このタイムアウトの制限値は、大きくしないでください。大きくした場合、アプリケーション全体のパフォーマンスに悪影響をもたらします。代案については、第 6 章「ASP.NET パフォーマンス」の「所要時間の長いタスクをブロックしない」を参照してください。

  • Worker process timeouts - The <processModel> 要素には、timeout、idleTimeout、shutdownTimeout、および responseDeadlockInterval といった属性があります。timeoutidleTimeout は、デフォルトでは無限に設定されています。これらの値は小さくしないでください。小さくした場合、(設定したしきい値に到達すると) プロセスが、負荷が高くかつ多大な時間を必要とするリサイクル処理を実行するため、アプリケーションのダウンタイムが生じてしまいます。

RequestQueueLimit を設定する

IIS と ASP.NET ワーカー プロセスの間には、ASP.NET に対する要求をキューに入れるのに使う、名前付きのパイプがあります。また、各仮想ディレクトリについてもキューがあります。

プロセス レベルでのキューについての 規定制限値は 5000 であり、以下のように、<processModel> 要素にある requestQueueLimit 属性によって指定されます。

<processModel enable="true" requestQueueLimit="5000" />

現在の要求数は、ASP.NET\Requests Current によって計測されます。現在の要求数 (キューに入れられた要求、実行中の要求、クライアントに書き込まれるのを待機している要求を含む) が requestQueueLimit に設定した値を超えると、ワーカー プロセスは、503 ステータス コードとメッセージ “Server Too Busy (サーバーが過負荷状態です)” を出して、その要求を拒否します。

それぞれの仮想ディレクトリ (あるいはアプリケーション) におけるキューの規定制限値は、100 です。この制限値は、Machine.config ファイルにある <httpRunTime> 要素の appRequestQueueLimit 属性によって指定されます。

(ASP.NET Applications\ Requests In Application Queue で計測された) アプリケーション キューにある現在の要求の数が、各仮想ディレクトリについて規定のしきい値設定を超えると、ユーザーは 503 ステータス コードとエラー メッセージ “Server Too Busy (サーバーが過負荷状態です)” を受信します。要求数が Machine.config ファイル内の appRequestQueueLimit の値を超えると、要求は拒否されます。

プロセス キューについての規定値は、最適化されています。この値は、appRequestQueueLimit 属性の値に、仮想ディレクトリの総数を掛けたものとほぼ同じになっています。

メモ: .NET Framework version 1.1 のバグが原因で、IIS 6.0 実行時、ASP.NET は無限数の要求を処理してしまいます。サポート技術文書 821156 「[INFO] ASP.NET 1.1 修正プログラム ロールアップ パッケージ (2003 年 6 月)」 ( http://support.microsoft.com/default.aspx?scid=kb;ja;821156 ) で入手できる修正プログラムは、Requests Current の値が requestQueueLimit の値を超えたときに、ASP.NET に要求を拒否させるためのものです。

appRequestQueueLimit の規定値は (仮想ディレクトリごとに) 100 となっていますが、数件のアプリケーション (あるいはひとつのアプリケーション) しかないサーバーにとっては、少ない値です。この値を徐々に大きくし、要求が拒否され始めた時点で、アプリケーションのパフォーマンス (スループット、応答時間など) を計測します。キューに入れられた要求についての応答時間は、アプリケーションのパフォーマンス目標で定義されたレベルを超えてはなりません。もしも超えてしまった場合は、おそらく要求がキューに入れられたまま、非常に長い時間処理されるのを待つことになってしまうため、キューの制限値を大きくしておいても、何の役にも立ちません。

requestQueueLimit の値は、実際には、すべての仮想ディレクトリについての、キューに入れられた要求、実行されている要求、クライアントへの書き込みを待機している要求の合計数の制限値となるので、全仮想ディレクトリの appRequestQueueLimit の合計値よりも大きくなるように設定します。

トレースとデバッグを無効にする

Machine.config ファイルと Web.config ファイルにおいて、以下のようにトレースとデバッグを無効化します。

<configuration>
<system.web>
<trace enabled="false" pageOutput="false" />
<compilation debug="false" />
</system.web>
</configuration>

詳細情報については、Microsoft サポート技術情報の Knowledge Base の文書 815157 「HOW TO: ASP.NET アプリケーションのデバッグを使用しないでください」 ( http://support.microsoft.com/default.aspx?scid=kb;ja;815157 ) を参照してください。

メモ: 個々のページで、トレースとデバッグの機能が有効になっていないことを確認する必要があるかもしれません。トレースとデバッグの設定は、Web.config ファイルの設定を無効にしてしまいます。

セッション状態を使わない場合は無効にする

セッションを使用していないときは、その機能を停止します。セッション機能を停止することで、ASP.NET のプロセスがユーザーごとにセッション オブジェクトを作成、保持することはなくなります。以下のように、Web.config ファイルの <sessionState> 要素にある mode 属性を “off” に設定することで、個々のアプリケーションについてセッション ステートを停止することが可能です。

<sessionstate mode="off" />

詳細情報については、第 6 章「ASP.NET パフォーマンスの向上」の「セッション ステート」を参照してください。

セッション状態を使うときは、タイムアウトを短くする

ユーザー情報は、セッションの有効期限が切れるまでは (規定値は 20 分) セッション状態に格納されます。クライアントが接続を絶つと、セッションはアクティブのままとなり、セッション状態はタイムアウトするまでリソースを消費し続けてしまいます。セッション状態を短くすることで、使用されていないセッションをより速くクリーンアップできます。セッション状態の短縮は、セキュリティの観点からも良い方法と言えます。

アプリケーションの Web.config ファイルにおいて、 要素にあるタイムアウト属性を変更することで、タイムアウト値の変更が可能です。以下のコードでは、規定値である 20 分 を示しています。

<:sessionState timeout="20" />

変更を評価する

セッション状態のタイムアウトに、小さすぎる値を設定すると、ユーザーのセッションは終了する頻度が高くなり、同一要求によるサイトへの重複ヒット数だけでなく、ユーザー不満度も増大させる恐れがあります。タイムアウトに大きすぎる値を設定すると、サーバー リソースが長時間消費されるので、アプリケーションのスケーラビリティに悪影響が出ます。

セッションのタイムアウト値は最適化することが必要です。セッションのタイムアウトとして最適な値を特定する方法についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「ASP.NET」にある「セッション」を参照してください。

必要なければビュー ステートを無効にする

ビュー ステートの無効化については、そのレベルに応じてさまざまな方法があります。

  • Web サーバー上のすべてのアプリケーションについて、ビュー ステートを無効にする場合は、Machine.config ファイルの <pages> 要素を以下のように設定します。
    <pages enabledViewState="false" />
    

    この方法を使えば、@ Page ディレクティブの EnableViewState 属性を使って、必要とするページについてのみ、選択的にビュー ステートを有効化できます。

  • ある 1 ページについてのみ、ビュー ステートを無効にする場合は、以下のように、@ Page ディレクティブを使います。
    <%@ Page EnableViewState="false" %>
    
  • あるページ上のひとつのコントロールについて、ビュー ステートを無効にする場合は、そのコントロールの EnableViewState プロパティを、以下のように false に設定します。
    // プログラム的に
    yourControl.EnableViewState = false;
    // 何らかの処理
    <asp:datagrid EnableViewState="false" runat="server" />
    

詳細情報

詳細情報については、第 6 章「ASP.NET パフォーマンスの向上」の「ビュー ステート」を参照してください。

サイズの大きなファイルをアップロードするときは maxRequestLength を考慮する

アプリケーションがサイズの大きなファイルをアップロードすることが必要な場合、規定値により、4 MB を超えるものは許可されないことに注意してください。規定値を変更するには、Machine.config ファイル内の <httpRuntime> 要素にある、maxRequestLength 属性に、適切な値を設定してください。

詳細情報

詳細情報については、Microsoft サポート技術情報の Knowledge Base の文書 295626 「[PRB] HtmlInputFile サーバー コントロールを使用するとサイズの大きなファイルをアップロードできない」 ( http://support.microsoft.com/default.aspx?scid=kb;ja;295626 ) を参照してください。

プロセッサ アフィニティがメリットとなるシナリオでは Web ガーデンを考慮する

アプリケーションが過度に STA コンポーネントを使用する場合、あるいはプロセッサ アフィニティがメリットとなるような技術を使っている場合、Web ガーデンの考慮が必要になることがあります。特定のプロセッサに対するアフィニティは、頻度の高い CPU キャッシュ (L1 あるいは L2 キャッシュ) のヒットをうまく利用しています。

Web ガーデンがシナリオのパフォーマンスを改善しているかどうか、常にテストし、判断することが必要です。一般的には、ほとんどのアプリケーションについて Web ガーデンを推奨しません。

デフォルトでは、IIS 5 Web サーバー上では、ASP.NET ワーカー プロセスはひとつしかありません。Machine.config ファイルの <processModel> 要素の webGarden 属性を true にセットして、複数のプロセッサ サーバー上で、適性のあるプロセッサごとに複数のワーカー プロセスを作成することが可能です。

cpuMask 属性をセットすることで、適性のあるプロセッサを指定できます。この属性は、ASP.NET スレッドを実行する適性をもつ CPU を示すビット パターンを指定します。たとえば、cpuMask の 16 進数の値である 0x0d は、ビット パターン 1101 を表します。このビット パターンは、4 つのプロセッサをもつサーバー上では、ASP.NET プロセッサを CPU 0、2、3 についてはスケジュールできますが、CPU 1 についてはできないことを示します。webGarden がデフォルトで true にセットされている場合は、すべての CPU が有効となっていて、ASP.NET は、それぞれの CPU について、ひとつのプロセスを開始します。webGardenfalse にセットされている場合は、cpuMask 属性は無視され、サーバー上で実行されるワーカー プロセスはひとつだけとなります。

これらの属性の規定値は以下のとおりです。

<processModel webGarden="false" cpuMask="0xffffffff" />

要求は、ラウンドロビン方式で複数のプロセッサ間で分散されます。この場合、各プロセスには、特定のプロセッサに対するアフィニティがあります。

IIS 6.0 Web サーバー上では、アプリケーション プールごとに複数のワーカー プロセスを作成できます。このようなプロセスは、特定のプロセッサに対するアフィニティをもつ可能性があります。

Web ガーデンの使用を検討しているときは、以下の落とし穴に注意してください。

  • キャッシュ、セッション、アプリケーション状態は、異なるプロセス間では共有されません。したがって、各プロセスは、キャッシュやアプリケーション状態のコピーを必要とします。アウトプロセスのセッション状態を、状態サービスあるいは SQL サーバー データベースに格納し、プロセス間で共有することが可能です。アウトプロセス セッション状態は、さらに、シリアル化、プロセス間通信あるいはサーバー間通信といったオーバーヘッドを生じさせます。
  • Web ガーデン使用時は、複数のプロセスを使用するため、サーバーのメモリ要件が増大します。

詳細情報

Web ガーデン、パフォーマンス向上をもたらす可能性をもつシナリオおよび IIS 6.0 の展開上の考慮事項についての詳細情報は、第 6 章「ASP.NET パフォーマンス」の「展開上の考慮事項」と “Web and Application Server Infrastructure - Performance and Scalability” ( http://www.microsoft.com/technet/prodtechnol/windowsserver2003/technologies/webapp/iis/iis6perf.mspx ) を参照してください。

補足的な考慮事項

前述の、ASP.NET アプリケーションのための主要チューニング オプションに加え、以下の補足的な考慮事項があります。

  • ページとコンパイルについてのチューニング - ASP.NET は、ディレクトリ内のすべてのページについて、最初のページ要求時に、単一のアセンブリへのコンパイルを実行します。通常は、アセンブリの数を少なくするのが望ましいので、バッチ コンパイルと呼ばれるこの機能にはメリットがあります。ディレクトリ内のページが何百ページもある場合、必要なコンパイル作業の量によっては、最初のページ要求の実行に長い時間がかかる可能性があります。

    バッチ コンパイルにおけるタイムアウトは、<compilation> 要素の batchTimeout 属性で指定します。この値を超えると、バッチ コンパイルはバックグラウンド スレッドで継続し、要求されたページは個々にコンパイルされます。

    batchTimeout の規定値を修正しないでください。むしろ、過剰な数のページを使わないよう、アプリケーションを設計してください。たとえば、大量の静的ページを使わず、クエリ文字列を使うことによって、動作の異なる動的ページを少数作成することを検討します。

  • HTTP パイプラインの短縮 - ユーザー要求は HTTP パイプライン内で指定されるさまざまなモジュール間を移動します。このような要求を Web.config ファイルおよび Machine.config ファイルで定義します。アプリケーションが使用していないモジュールを除去することによって、モジュールがもたらす不要なオーバーヘッドを回避します。このようなパフォーマンスの改善が、アプリケーションにとって意義のあるものかどうかを計測して確認します。

    たとえば、Web アプリケーションがフォーム認証を使用していない場合は、以下のエントリを Web.config に追加することで、FormsAuthentication モジュールを除去することができます。

    <httpModules>
    <remove name="FormsAuthentication" />
    </httpModules>
    

Enterprise Services のチューニング

Enterprise Services のパフォーマンスをチューニングするときは、作成、破棄、プーリングを含めたコンポーネントのライフタイムの最適化に照準を合わせます。

構成の概要

ほとんどの Enterprise Services のチューニングでは、Enterprise Services アプリケーションと処理されるコンポーネントについて、COM+ カタログで保持される設定を微調整するための、コンポーネント サービス管理ツールを使用することが必要です。

メトリクス

Enterprise Services アプリケーションの統計に関するパフォーマンスを監視するのに、コンポーネント サービス ツールを使うことができます。このツールにより、以下を監視できます。

  • 起動したオブジェクトの数
  • 使用中のオブジェクトの数
  • オブジェクトが呼び出されている期間
  • トランザクション終了に必要なリソースと時間という観点から見た、トランザクションのコスト
  • オブジェクト上のメソッド呼び出しにかかるプロセッサとメモリのコスト
  • オブジェクト プールの最適なサイズ

上記の値の計測方法、しきい値および意味についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「Enterprise Services」を参照してください。

図 17.13 に統計情報を示します。

コンポーネントの統計情報を示すコンポーネント サービス ツール

図 17.13: コンポーネントの統計情報を示すコンポーネント サービス ツール

チューニング オプション

Enterprise Services アプリケーションのチューニングには、以下の選択肢があります。

  • アプリケーション プール サイズをチューニングする。
  • オブジェクト プール サイズをチューニングして、しきい値を設定する。
  • サーバー アプリケーションについてアイドル時間管理を最適化する。
  • 暗号化が必要なときだけパケット プライバシーを使う。
  • クライアントが Dispose を呼び出さないときだけ DisableAsyncFinalization を設定する。

アプリケーション プール サイズをチューニングする

アプリケーション プーリングにより、シングル スレッド プロセスのスケーラビリティが向上し、また回復力も向上します。あるプロセスに障害が生じても、他の実行中のプロセスがクライアント要求を処理できます。この機能は、COM+ 1.5 で使用可能です。

同時実行可能なプロセスの数はアプリケーション プール サイズにより決定します。規定値はゼロ (0) で、アプリケーション プーリングが無効となっていることを示します。図 17.14 に示すように、アプリケーションの Properties ダイアログ ボックスにある Pooling & Recycling ページで、この値を大きくすることが可能です。

メモ: このオプションは、サーバー アプリケーションでのみ使用可能で、ライブラリ アプリケーションでは使用できません。

アプリケーション プーリングの構成

図 17.14: アプリケーション プーリングの構成

通常は、アプリケーションのリサイクル設定に変更を加える必要はありません。この設定についての詳細情報は、以下の資料を参照してください。

  • 第 8 章「Enterprise Services パフォーマンスの向上」の「最小プール サイズ値が大きなアプリケーションをプリロードする」
  • “Configuring COM+ Application Recycling Values” ( http://msdn2.microsoft.com/en-us/library/ms684192 )

オブジェクト プール サイズをチューニングして、しきい値を設定する

オブジェクト プール サイズをチューニングして、しきい値を設定します。アプリケーション開始時に、Dllhost.exe のサロゲート プロセスが初期化され、オブジェクト プールには最小プール サイズ設定により決定した指定数のオブジェクトが投入されます。以下のような場合は、オブジェクト プーリングの使用を検討してください。

  • アプリケーションに、作成や初期化すると高い負荷を生じさせるオブジェクトが含まれる。たとえば、オブジェクトが、接続に高い負荷がかかるリモート リソースのデータを取得する必要があるときや、保守データベースへの接続、何千というレコード間での複数テーブル結合の実行などもこの例です。
  • 複数のクライアント呼び出しでオブジェクトの再利用が可能である。再利用するオブジェクトに、要求とユーザー固有の状態が含まれていないこと。
  • アプリケーションに、クライアントが同時接続するようなバースト処理が含まれる。

アプリケーションが、上記のいずれかの条件を満たしているときは、以下のガイドラインを考慮します。

  • 適切な最小プール サイズを設定して、オブジェクトを事前に割り当てます。そうすることで、受信クライアント要求に対し、オブジェクトをすぐに使用できます。
  • リソース使用についてのしきい値を設定する必要があるときは、最大プール サイズを設定します。そうすることで、(該当する場合) ライセンスのルールに適合できます。たとえば、特定のライセンスについて、一定の数だけのクライアント接続を許可するようなルールがある場合が、この例です。

図 17.15 に示すように、アプリケーションの Properties ダイアログ ボックスの Activation タブで、オブジェクト プーリングを設定します。

コンポーネント サービスでのオブジェクト プーリング設定

図 17.15: コンポーネント サービスでのオブジェクト プーリング設定

メモ: これらの設定の最適値を判断するため、特定のシナリオについてのパフォーマンスをテスト、計測する必要があります。

詳細情報については、“Improving Performance with Object Pooling” Avnish(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cossdk/htm/pgservices_objectpooling_9wbr.asp) を参照してください。

サーバー アプリケーションについてアイドル時間管理を最適化する

設定したクライアントの活動停止時間が過ぎると、COM+ ホスト プロセス (Dllhost.exe) はシャットダウンします。デフォルトでは、この時間は 3 分です。クライアントが、アプリケーションに対し、散発的な間隔で、バースト アクセスを行う場合は、規定時間を延長する必要があるかもしれません。アイドル時間を設定するには、コンポーネント サービスを使い、アプリケーションの Properties ダイアログ ボックスにある Advanced ページを使用します。1 ~ 1440 分の範囲の値がサポートされます。

暗号化が必要なときだけパケット プライバシーを使う

呼び出し元を認証して、クライアントと処理されるコンポーネントとの間のトランジット中にパケットが改ざんされていないことを確認することが必要な場合は、暗号化は不要です。処理されるコンポーネントとの間で送受信されるデータの機密性を保証する必要がある場合は、パケット プライバシー認証の使用を考慮します。

ただし、IPSec 暗号化を使って、サーバー間の通信チャネルを保護しているといった、セキュリティ保護されたネットワーク内にアプリケーションが存在する場合は、パケット プライバシー認証を使用しなくてもかまいません。パケット プライバシー認証のレベルは、図 17.16 で示す、アプリケーションの Properties ダイアログ ボックスの Security ページで設定できます。

認証レベルの設定

図 17.16: 認証レベルの設定

詳細情報については、第 8 章「Enterprise Services パフォーマンスの向上」の「暗号化が必要なときだけパケット プライバシー認証を使う」を参照してください。

メモ: このオプションは、サーバー アプリケーションでのみ使用可能で、ライブラリ アプリケーションでは使用できません。

クライアントが Dispose を呼び出さないときだけ DisableAsyncFinalization を設定する

クライアント コードが、処理されたコンポーネントを開放する最後の手段として、Dispose を呼び出さない場合、DisableAsyncFinalization レジストリ キーの使用を検討します。この機能を有効にするには、以下のレジストリ キーを作成します。

HKLM\Software\Microsoft\COM3\System.EnterpriseServices
DisableAsyncFinalization = DWORD(0x1)

詳細情報については、第 8 章「Enterprise Services パフォーマンスの向上」の「DisableAsyncFinalization レジストリ設定」を参照してください。

メモ: 管理者は、サーバー上のリソースを開放する Dispose メソッドを呼び出すため、クライアント実装があるるかどうかを、開発チームに確認する必要があります。このレジストリ キーの変更を検討するのは、最後の手段とします。

Web サービスのチューニング

ASP.NET Web サービスでは、ASP.NET アプリケーションと同一の ASP.NET ランタイムを使います。そのため、前述のチューニング ガイドラインを Web サービスにも適用します。Web サービスに必要な考慮事項について説明します。

チューニング オプション

以下のチューニングの選択肢を考慮します。

  • 競合を削減するための方策を用いてスレッド プールをチューニングする。
  • maxconnections を設定する。
  • 個々の Web サービスの接続に優先順位をつけ、割り当てる。
  • responseDeadlockInterval 属性を考慮する。
  • サイズの大きなファイルをアップロードするときは maxRequestLength を設定する。

競合を削減するための方策を用いてスレッド プールをチューニングする

他の Web サービスを呼び出す ASP.NET サーバー上で、スレッド プールと接続設定をチューニングします。maxWorkerThreadsmaxIoThreads などの他の設定に関連して maxconnection を設定する方法についての詳細な説明は、第 10 章「Web サービス パフォーマンスの向上」の「スレッド処理」と、この章の「ASP.NET のチューニング」にある「スレッド プール属性」を参照してください。

maxconnections を設定する

Machine.config ファイルにある maxconnection 属性は、同時実行される呼び出しの送信数を制限します。

メモ: この設定は、ローカル要求 - Web サービスと同じサーバー上にある ASP.NET アプリケーションから送信される要求 - には適用されません。現行のコンピュータから、たとえば他のリモートの Web サービスを呼び出す ASP.NET アプリケーションや Web サービスに対して送信される接続に対しては適用されます。

maxconnection の規定値は、接続グループごとに 2 となっています。Web サービスを呼び出すデスクトップ アプリケーションでは、接続数は 2 で十分でしょう。Web サービスを呼び出す ASP.NET アプリケーションでは、接続数は、通常は 2 では足りません。出発点として、maxconnection 属性を規定値の 2 から(12 x CPU 数) に変更します。

<connectionManagement>
<add address="*" maxconnection="12" />

</connectionManagement>

12 x CPU 数という接続数は、任意の数ではありますが、ASP.NET での同時実行要求数を 12 に制限している場合は、多くのシナリオに最適な数であることが経験的に実証されています。シナリオに合わせて適切な接続数を確認してください。

maxconnection 属性の値を大きくすることで、スレッド プールとプロセッサの使用率も高くなります。maxconnection の値を大きくすると、Web サービスに対して同時呼び出しを行うため、より多くの I/O スレッドが使用可能になり、結果として、受信する HTTP 要求の処理もより高速になります。

変更する前に

接続数の増加は、使用可能な CPU があるときだけの考慮事項です。前述したように、属性の値を大きくすると、プロセッサの作業量も増大するので、属性の値を大きくする前に、常にプロセッサ使用率をチェックする必要があります。したがって、この属性の値を大きくするのは、プロセッサ使用率が、そのしきい値 (75 %などの) を下回っているときのみ、道理にかなっているといえます。

詳細情報については、この章の「ASP.NET のチューニング」を参照してください。

変更の評価

属性を変更すると、チューニング作業が何度も反復される可能性があり、また実際にスレッド プール使用に関するさまざまなトレードオフを生じさせます。したがって、maxconnection 属性の変更は、maxWorkerThreadsmaxIoThreads などの他のスレッド プール関連の構成属性の変更を必要とすることがあります。

構成に変更を加えた後に、アプリケーションの負荷テストを実施する場合は、CPU 使用率を監視し、ASP.NET Applications\Requests/secASP.NET Applications\Requests in Application Queue のパフォーマンス カウンタを観察します。Requests in Application Queue は減少し、Requests/sec と CPU 使用率は増加するはずです。

個々の Web サービスの接続に優先順位をつけ、割り当てる

呼び出す Web サービスを列挙し、優先順位をつけます。重要な Web サービスには、より多くの数の接続を割り当てます。以下のように address 属性を使って、それぞれの Web サービスを指定します。

<connectionManagement>
<add address="WebServiceA" maxconnection="8">
<add address="WebServiceB" maxconnection="4">
</connectionManagement>

たとえば、アプリケーションが WebServiceB よりも Web ServiceA に対してより多くの要求を行っている場合、上記の例のように、より多くの数の接続を Web ServiceA に割り当てることができます。

responseDeadlockInterval 属性を考慮する

ASP.NET アプリケーションから Web サービス呼び出しを行うときは、何らかの理由でプロキシのタイムアウトと executionTimeout の両方を 180 秒を超える値に変更している場合、machine.config ファイル内の processModel 要素 にある responseDeadlockInterval 属性の変更を検討します。この属性の規定値は 180 秒です。実行中の要求について応答が 180 秒間ない場合は、ASP.NET ワーカー プロセスのリサイクルが行われます。

これらの属性の値を大きくすることが必要な場合は、設計を見直すことが必要です。

サイズの大きなファイルをアップロードするときは maxRequestLength を設定する

ASP.NET ランタイム設定により、4 MB を超えるファイルはアップロードできません。この規定値を変更するには、<httpRuntime> 要素にある maxRequestLength パラメータを、任意の値に変更することが必要です。

詳細情報

詳細情報については、以下の資料を参照してください。

  • 第 10 章「Web サービス パフォーマンス」の「バルク データ転送」
  • Microsoft サポート技術情報の Knowledge Base の文書 295626「[PRB] HtmlInputFile サーバー コントロールを使用するとサイズの大きなファイルをアップロードできない」 ( http://support.microsoft.com/default.aspx?scid=kb;ja;295626 )

リモート処理のチューニング

リモート処理においてチューニングを行う主要構成設定は、リース期限です。アプリケーションについて、適切なライフタイムのタイムアウトを割り出す場合、サーバーにおけるリソース使用率と、破棄・再作成される頻度の高いオブジェクトのパフォーマンス予測との間のバランスを取る必要があります。オブジェクトのライフタイムを長くすると、サーバーのメモリとリソースの使用率が上昇し、その反対にライフタイムを短くすると、オブジェクトは頻繁かつ期限前に破棄されてしまいます。

チューニング オプション

一般的なガイドラインは次のとおりです。

  • 作成に高い負荷のかかるオブジェクトについてはリース期間を長くすることを検討する。
  • 共有リソースあるいは重要リソースを大量に消費するオブジェクトについてはリース期間を短くすることを検討する。

作成に高い負荷のかかるオブジェクトについてはリース期間を長くすることを検討する

作成に高い負荷がかかるオブジェクトを使う場合は、リースのタイムアウトを変更して、そのオブジェクトがタイムアウト規定値である 5 分よりも長く存続できるようにすることを検討します。たとえば、負荷の高い起動プロセスをもたらすシングルトン オブジェクトを使う場合、タイムアウトを、より長い適切な数値あるいは無限に設定します。

共有リソースあるいは重要リソースを大量に消費するオブジェクトについてはリース期間を短くすることを検討する

共有リソースまたは重要リソースを消費するオブジェクトを作成する場合は、リースのタイムアウトを短くすることを検討します。タイムアウトを 5 分未満に設定すると、リソースのクリーンアップがより早く実施され、リソースの孤立やリソース プレッシャーを回避するのに役立ちます。

リース期限のチューニング

リースのタイムアウトと「呼び出し時更新」の両方を、プログラム的にあるいは構成設定で、チューニングすることが可能です。以下の構成ファイルで、その設定方法を示します。

<configuration>
<system.runtime.remoting>
<application>
<lifetime leaseTimeout="1M"
renewOnCallTime="30S"
leaseManagerPollTime="2M" />
</application>
</system.runtime.remoting>

</configuration>

この方法を使うと、サーバーが発行したすべてのリモート オブジェクトが変更されることに注意してください。

ADO.NET のチューニング

ADO.NET における主要構成オプションは、接続文字列です。接続に使うアイデンティティ、アプリケーションが使う接続の数、プール接続のプール数およびデータベースへの接続を試みる回数を考慮する必要があります。

構成の概要

接続文字列の設定は、接続文字列が格納されている場所により異なります。セキュリティ上の理由で、接続文字列は、極力暗号化されたフォーマットで格納する必要があります。

メトリクス

以下のパフォーマンス カウンタを使えば、ADO.NET ボトルネックを特定できます。

表 17.8: ADO.NET ボトルネックを特定するのに使うパフォーマンス カウンタ

カテゴリカウンタ
Connection Pooling
(接続プーリング)
・ .NET CLR Data\SqlClient: Current # pooled connections
・ .NET CLR Data\SqlClient: Peak # pooled connections
・ .NET CLR Data\Total # failed connections

これらのカウンタの計測方法、しきい値、意味についての詳細情報は、「ADO.NET / データ アクセス」第 15 章「.NET アプリケーション パフォーマンスの計測」を参照してください。

ボトルネック

以下のリストで、AOD.NET を使うアプリケーションで発生する一般的なボトルネックと、システム カウンタを使ってそれらのボトルネックを特定する方法について説明します。

多すぎる接続数

多すぎる接続数の原因となるのは、不適切なコーディング方法または不適切な接続文字列設定因です。この兆候を特定するには、以下のパフォーマンス カウンタを監視します。

  • Logins/sec カウンタと Logouts/sec カウンタを示す SQLServer:General Statistics オブジェクトは、ゼロに近い値でとどまっていなければなりません。ゼロより大きい値のままであれば、接続プールが使用されていないことを示します。
  • SQLServer:General Statistics オブジェクト が User Connection が一定期間にわたって安定せず増大していくのを示す場合は、恐らく接続リークがあったことを示します。

詳細情報については、第 12 章「ADO.NET パフォーマンスの向上」の「プーリングの監視」を参照してください。

チューニング オプション

ADO.NET データ アクセスのチューニングは、たいていの場合、データベースへの接続に使用する接続文字列のチューニングを必要とします。接続文字列を使用して、データベース接続のプール サイズを設定できます。すべての接続に対して、一貫した接続文字列を使用するように設定することが重要です。接続文字列に少しでも変更があると、新規のプールが使用されてしまいます。

同一の接続文字列にあるのは、パフォーマンスに影響を与える可能性のある一連の属性です。これらの属性は、パフォーマンス、セキュリティおよびネットワーク使用率に関するトレードオフを考慮しながら、一般的なシナリオのほとんどに適合するよう最適化されています。規定値の変更を検討している場合は、.NET Framework クラス ライブラリの「SqlConnection.ConnectionString プロパティ」 ( http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpref/html/frlrfSystemDataSqlClientSqlConnectionClassConnectionStringTopic.asp ) を参照してください。

必要に応じてプール サイズのチューニングを検討する

接続プール サイズを設定できます。たとえば、SQL Server 用の .NET Framework データ プロバイダの場合、最小プール サイズの規定値 0、最大サイズの規定値は 100 です。最小サイズを大きくして、ウォームアップ時間を削減することが必要になるかもしれません。稀なケースではありますが、アプリケーションが 100 を超える接続数を必要とする場合は、最大サイズを大きくすることが必要となる可能性もあります。

データベース接続プールの健全性の計測についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」を参照してください。

SQL Server のチューニング

ほとんどの場合、SQL Server は、セルフ チューニングを行うため、構成設定の規定値を変更する必要はありません。どうしても変更を加えたいという場合は、テストを実行して、その変更が問題点を解消し、パフォーマンス目標を満足させるのに役立つことを確認してください。

メトリクス

以下のパフォーマンス カウンタを使えば、SQL Server に関するボトルネックを特定できます。

表 17.9: SQL Server ボトルネックを特定するのに使うパフォーマンス カウンタ

カテゴリカウンタ
Indexes
(インデックス)
SQLServer: Access Methods\Index Searches/sec
SQLServer: Access Methods\ Full Scans/sec
Cache
(キャッシュ)
SQL Server: Cache Manager\ Cache Hit Ratio
SQL Server: Cache Manager\Cache Use Count/sec
SQL Server: Memory Manager\ SQL Cache Memory(KB)
Memory\ Cache Faults/sec
Transactions
(トランザクション)
SQL Server: Databases\Transactions/sec
SQL Server: Databases\Active Transactions
Locks(ロック)SQL Server: Locks\ Lock Request/sec
SQL Server: Locks\ Lock Timeouts/sec
SQL Server: Locks\Lock Waits/sec
SQL Server: Locks\ Number of Deadlocks/sec
SQL Server: Locks\Average Wait Time (ms)
SQL Server: Latches\Average Latch Wait Time(ms)

これらのカウンタ値の計測方法、しきい値、意味についての詳細情報は、第 15 章「.NET アプリケーション パフォーマンスの計測」の「ADO.NET / データ アクセス」を参照してください。

ボトルネック

期限切れの統計情報は、SQL Server における代表的なボトルネックとなります。SQL クエリ オプティマイザが使用する統計情報が期限切れとなっている場合、パフォーマンスの低下を招くことがあります。このような統計情報を監視するのに、クエリ アナライザのSET STATISTICS PROFILE ON を使用する方法、あるいは SQL プロファイラを使って、Performance:Showplan Statistics (Event Class 98) という名前の付いたプロファイラ イベントを監視するという方法のいずれかを使えます。予測した行数と実際の行数に大きな差異がある場合は、オプティマイザは、期限切れあるいは歪曲された統計値を保持していた可能性があります。詳細情報は、第 14 章「SQL Server パフォーマンスの向上」の「実際の行数・実行数と、予測した行数と実行数とを比較する」を参照してください。

チューニング オプション

(アプリケーションとデータベースの設計に既にチューニングを行った後で) 残っている最後の手段ということでない限り、一般的には、SQL Server の構成設定のチューニングは行いません。チューニングは、SQL Server のセルフ チューニングに悪影響を与え、パフォーマンスを低下させる可能性があります。この問題が解決していることを確認するテストを必ず実施してください。

SQL Server のチューニングを行うときは、以下の選択肢を考慮します。

  • システム上に他のアプリケーションがあるときは、SQL Server のメモリ量を固定する。
  • 統計情報を更新する。
  • 可能なら、ソフトウェア RAID ではなくハードウェア レベルの RAID を選択する。

システム上に他のアプリケーションがあるときは、SQL Server のメモリ量を固定する

システムが SQL Server 以外のアプリケーションを実行しているときは、SQL Server に固定量のメモリを割り当てます。そうしないと、SQL Server に可能な限りの量のメモリを割り当ててしまう可能性があります。SQL Server に固定量のメモリを割り当てるには、サーバーの SQL メモリ設定で、「固定メモリサイズを使用する」ように設定する必要があります。この値は、アプリケーションと SQL Server にかかる負荷によって異なるので、値を変更し、アプリケーションと SQL Server にかかる負荷を用いてサーバーをテストして、この設定に最適な値を割り出すことを検討してください。

統計情報を更新する

統計情報の期限が切れていると、インデックスの効率が悪くなります。期限切れの統計情報は、UPDATE STATISTICS WITH FULLSCAN を使って更新できます。

可能なら、ソフトウェア RAID ではなくハードウェア レベルの RAID を選択する

可能であれば、ソフトウェア RAID ではなくハードウェア レベルの RAID を選択します。ソフトウェア RAID は SQL Server の CPU サイクルを消費してしまいます。

<3>可能なら、RAID 0+1 (ミラー化ストライピング) を選択する

可能であれば、RAID 0+1 (RAID 01 あるいはミラー化ストライピングとも言います) を使います。状況によっては RAID 5 (パリティ付きストライピング) を使えますが、一般的には信頼性が低く、長期に渡ると高い負荷を生じさせます。

インターネット インフォメーション サービス (IIS) のチューニング

IIS のチューニングは、このガイド全体のテーマであり、きちんと扱うとこの章の範囲をはるかに超えてしまいます。しかしながら、この章では、一般的な問題点に注目し、より重要な構成設定のいくつかを特定します。詳細情報は、章末に記載した参考資料で入手できます。

  • ツールを把握する - IIS メタベースおよび Windows レジストリには、IIS サーバーの動作を制御する設定が含まれています。Adsutil および MetaEdit を使ってこの設定を変更することが可能です。詳細情報については、Microsoft サポート技術情報の Knowledge Base の文書 240225 「[IIS]メタベースを修正する Adsutil と MetaEdit ユーティリティ」 ( http://support.microsoft.com/default.aspx?scid=kb;ja;240225 ) を参照してください。

    IIS 管理コンソール (インターネット サービス マネージャ) を使って、セッション状態とデバッグ設定 (不要であれば両方とも無効にすること) を設定することも可能です。これらの設定を図 17.17 に示します。

    セッション状態とデバッグ設定を示す IIS コンソール

    図 17.17: セッション状態とデバッグ設定を示す IIS コンソール

  • 監視方法を理解する - システム モニタには Web サーバーのパフォーマンスを監視するための豊富なカウンタがあります。図 17.18 に、Web Service のいくつかのカウンタを示します。

    システム カウンタの Web Service カウンタ

    図 17.18: システム カウンタの Web Service カウンタ

詳細情報

以下の記事は、Web サーバーのチューニングのさまざまな局面についての詳細情報を載せています。

まとめ

パフォーマンス チューニングとは、コードの最適化とアプリケーションの構成設定を意味します。この章では、構成に焦点を合わせ、パフォーマンス向上に向けて、システム、プラットフォーム、アプリケーションの各レベルでの構成パラメータをチューニングする方法を説明しています。この章で扱う主要テクノロジ関連カテゴリについては、ボトルネックを特定し、解消する方法を学習しました。

この章で説明するパフォーマンス チューニングの方法を使えば、ボトルネックをシステム的に特定し、解消できます。ベースライン メトリクスの取得からスタートし、テストを実施してデータの収集と解析を行い、ボトルネックを特定し、構成設定をチューニングします。一度に適用する構成関連の変更は、1 組とします。最後に加えた変更の影響を確認するため、必ず再テストを行い、パフォーマンスを計測してください。

パフォーマンス チューニングは、反復プロセスです。アプリケーションがその目標値に適合するまで、またはコードあるいはアプリケーションの設計がさらに最適化を必要としていると判断するまでは継続してください。

補足資料

パフォーマンスのチューニングについての詳細情報は、このガイドの以下の資料を参照してください。

さらに詳しい内容については、以下の資料を参照してください。

  • “ASP.NET Performance Monitoring, and When to Alert Administrators” (著者: Thomas Marquardt、 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/monitor_perf.asp
© 2012 Microsoft. All rights reserved. 使用条件 | 商標 | プライバシー
Page view tracker