見落とされやすいパフォーマンス問題の原因

こんにちは。SharePoint サポートチームの荒川です。
これまでにも何度かブロッキング関連のトラブルについて記事を書いてきましたが、今回は見落とされやすいブロッキング要因について解説します。

 

この記事の趣旨

一つのコンテンツデータベースにデータ量が多いサイトコレクションとデータ量の少ないサイトコレクションを混在させた場合、パフォーマンスおよびブロッキング問題の原因になることがあるため、データ量が多いサイトコレクションには専用のコンテンツデータベースを設けることを強くお勧めします。

 

問題シナリオ

以下の問題について考えます。

サイトにアクセスするとしばらく (30秒から1分以上) 待たされ、サイトが開けることもあるがタイムアウトエラーになりアクセスできないこともある。この問題は時々発生し、すべての Web サーバーを IIS リセットするか、SQL サーバーを再起動またはフェールオーバーすることで改善されるがしばらくすると再発する。

 

上記のような問題が発生している場合、可能性が高い原因として SQL サーバーのブロッキング問題が挙げられます。
ブロッキング問題が発生しているときの特徴には以下のようなものがあり、これらの状況が複数一致しているようであればブロッキング問題に遭遇している可能性が高くなります。

  •  サイトにアクセスするとすぐにエラーになるのではなく、しばらく砂時計の状態で待たされる
  • 最終的にタイムアウトエラーとなる場合もあれば、一定時間で解消することもある
  • 問題が断続的に発生し、IIS リセットや SQL サーバーの再起動で解消される

ブロッキングが発生してクエリのパフォーマンスが低下している状況では、SharePoint の診断ログに以下のような「Slow Query Duration」の警告が複数出力されることがあります。このログはクエリが完了したタイミングで記録されるものになりますので、ブロッキングが長時間におよびクエリが全く成功しない状況ではログが出力されない場合もあり、一様に判断基準にすることはできませんが、パフォーマンス問題の診断の参考として利用できる情報です。

<診断ログの例>

07/01/2016 17:15:05.35 w3wp.exe (0x1234) 0x0123 SharePoint Foundation Database fa43 High Slow Query Duration: 4562406.84626119 c6dd1b44-7004-46ff-xxxx-d2b1b9ca5ec0

 

上記のログが出力される場合少なくとも SQL Server に対してクエリは実行されており、そのクエリの実行に時間がかかっているということが判断できますので、SQL Server 側のパフォーマンスに問題が生じており、ブロッキングの要因になっている可能性が考えられます。
このあたりの話は、以前に投稿した記事「SharePoint ブロッキング問題の調査手法」にも詳しく書いていますので、併せてご参照ください。

 

見落とされやすいパフォーマンス問題の原因

SQL ブロッキングの問題についてはこれまでも大量のコンテンツに対する更新処理が原因である場合が多いことをお伝えしてきましたが、一度の大量のコンテンツを更新しない場合であっても、SQL クエリの実行プランが原因でブロッキング問題が生じることがあります。

実行プランとは、例えば 2 つの条件を共に満たすようなクエリがあったとして、A条件を先に抽出した後で、B条件を抽出したほうが効率的なのか、逆のほうが効率的なのかを事前に登録された統計情報を基に判断して決定されたものです。SQL Server ではこのようなクエリの実行プランをキャッシュして再利用しています。

SQL Server は、クライアントから送信されてくるバッチ (クライアントから送信されてくるひとつ以上のステートメントの塊) をコンパイルし、バッチ内の各ステートメントの実行プランを生成し、その後、そのバッチを実行します。実行プランの生成過程であるクエリの最適化 (optimization) では、クエリの検索条件や結合条件などを参照し、最も低コストであると考えられる実行プランを選択します。

SharePoint では定期的なタイマージョブによってコンテンツ データベース内のテーブルの統計情報が更新されているため、統計情報が古いことが原因で最適なクエリプランが生成されないといった問題は起こりにくくなっています。しかしながら、一つのコンテンツデータベース内に、データ量が異なる複数のサイト コレクションが存在していた場合、全てのサイト コレクションにとって最適なクエリプランが生成されない可能性があります。

SharePoint では多くの場合ストアドプロシージャを使用してサイト内のデータを取得しています。例えば、コンテンツの取得の際に実行される代表的なストアドプロシージャの例として proc_FetchDocForHttpGet が挙げられます。このようなストアドプロシージャは、多くの場合サイトコレクションの ID を引数としており、さらに内部でサブクエリを実行して目的のデータを取得しています。

このような仕組みにおいて、例えばデータ量の少ないサイトコレクションで先に特定のストアドプロシージャに対するクエリプランが生成された場合、その際に生成されたクエリプランがデータ量の多いサイトコレクションにとっては非効率で適切ではない可能性があります。このような非効率なクエリプランが選択されると、結果的にデータの取得に必要以上の時間がかかってしまい結果として個々のクエリのパフォーマンスの低下を招きます。この問題は、対象となるデータの規模が大きくなるに従い顕著になり、場合によってはブロッキング問題を引き起こす要因になります。

このことは以下の TechNet 資料にも記載されていますが、ガイドラインとして大きく扱われていないため見落とされやすいポイントです。

チームのグループ作業サイトのベスト プラクティス (SharePoint Server 2010)
https://technet.microsoft.com/ja-jp/library/cc850694(v=office.14).aspx

パフォーマンスの最適化 チーム サイトを専用 Web アプリケーションにホストすると、チーム サイト コレクションのみを格納したコンテンツ データベースが複数作成されます。コンテンツ データベースが同じデータ特性を持つサイトをホストする場合、SQL Server はデータベースの特性に基づいたクエリ計画を使用するため、SQL Server データベース ソフトウェアの動作の効率が向上します。したがって、チーム サイトのコンテンツを専用データベースに配置することにより、SQL Server のパフォーマンスを最適化して、サーバー ファーム全体のパフォーマンスを向上させることができます。

 

SharePoint 2013 の設計サンプル: 企業ポータルおよびエクストラネット サイト
https://technet.microsoft.com/ja-jp/library/cc261995.aspx

アプリケーションは、類似するデータ特性を持つ他のアプリケーションと共に Web アプリケーションに配置した場合の方が、パフォーマンスが高くなります。たとえば、個人用サイトには、サイトの規模は小さいが、数が多いというデータ特性があります。それに対し、チーム サイトには、数は少ないが規模が非常に大きいという傾向があります。これら 2 種類のサイトを別々の Web アプリケーションに配置することにより、データベースは特性の類似するデータで構成されるようになり、データベースのパフォーマンスが最適化されます。設計サンプルでは、個人用サイトとチーム サイトは、固有のデータ分離要件を持たず、同じアプリケーション プールを共有しています。それにもかかわらず、個人用サイトとチーム サイトを別々の Web アプリケーションに配置することにより、パフォーマンスを最適化しています。

 

まとめ

運用時にデータ規模が大きなサイト コレクションとなることが予測される場合には、設計段階においてそのようなサイトコレクションを専用のコンテンツデータベースに分離することで、パフォーマンスに関する問題を未然に防止することができます。

<関連資料>
SharePoint Server ファーム内の SQL Server のベスト プラクティス
https://technet.microsoft.com/ja-jp/library/hh292622.aspx