パフォーマンスチューニングの目的と流れを書いてみた

## はじめに
お客様環境などでパフォーマンス障害が発生してしまった際に、どのような観点、方法でボトルネックを調査し、チューニングしていったらよいか、まとめてみようと思います。
まずは、パフォーマンスチューニングの目的と流れについて記載してみます。

## 前提
パフォーマンスチューニングを行う対象のシステムは、Webサーバー(Apache)、APサーバー(Tomcat)、DBサーバー(Oracle)で構成される、シンプルなWebシステムを想定しています。

## パフォーマンスチューニングの目的
データ量の増加、利用者数、利用機能の増加等により、最初は問題が無かったシステムのパフォーマンスが悪化し、最悪の場合、業務に支障をきたすレベルのパフォーマンス障害となる事があります。

このような問題は、ハードウェアの増強、例えば高性能のCPUに載せ替えたり、CPU数、メモリを増やすといった事(インスタンスタイプの変更など)で一時的に改善する事はあっても、根本解決に至らない場合が多く、本番環境稼働後にパフォーマンス問題が発生すると、多くのリソース(人、時間)を要する事になります。

特にオンプレミス環境の場合、そもそも運用開始後にハードウェアの増強をする事自体が難しい場合が多い為、現在のシステム構成でパフォーマンスチューニングを行う必要がある場合が殆どです。
AWSなどのクラウド環境であれば、リソースを増やす操作は比較的容易にできますが、有償のミドルウェアを使っている場合のライセンスの兼ね合いや、運用コストの面を考えると、増強はそれなりに大変です。

このような状況下では、現状を分析する事で問題点、ボトルネックとなっている箇所を整理し、改善効果が最も大きなパフォーマンスチューニング手法を選択して実施する事が、最善の手段として挙げられます。
よって、パフォーマンスチューニングの目的とは、**限られたシステムリソースの中で、最大限のパフォーマンス効果を出すこと**になります。

なお、パフォーマンスチューニングは、やろうと思えば、いくらでも続ける事ができますが、長い時間をかけて細々とした改善を行うより、業務に支障が出ない状態に戻す事が最優先であるため、**なるべく早く、パフォーマンス問題が起きる前の状態に戻す**事を目的とします。

## パフォーマンスチューニングの流れ
#### 1. パフォーマンス問題の発生状況を確認
まず、ユーザーに確認するなどし、以下のような項目についてヒアリングします。
- パフォーマンス問題が発生し始めたのはいつ頃からか。
- パフォーマンス問題が発生し始めた前後に、アプリ・システム運用におけるイベントや変更は無かったか(OS、ミドルウェア、アプリケーションのバージョンアップ・パッチ適用、アンチウィルスソフトの設定の変更、大規模な組織変更(Group会社追加、従業員増加・・)、バッチ処理など)。
- 何の機能(操作)が遅いのか、また、どの位レスポンスタイムなのか。
※合わせて、**元々はどの位のレスポンスタイムだったか**を確認。
- 動作が遅い日、時間帯はいつか。特定の日・時間帯なのか、常に又は不定期なのか(月末、月初が遅い、出社、退社時間付近が遅いなど)。
- 特定のユーザーが遅いのか、全てのユーザーが遅いのか、特定の拠点からのアクセスが遅いのか。

など

※最初に、発生している事象を(可能な限り)正確に把握する事が非常に重要。
※遅くなった処理は、通常どの程度のレスポンスタイムだったかも確認しておき、この状態を最低限の改善目標とする。

#### 2. システム構成、ミドルウェアやアプリケーションのバージョンを確認
以下のような点を確認し、OS、ミドルウェア、アプリケーションのバージョン固有の問題が無いか等を確認します。
- サーバースペック
- 各種ミドルウェアのバージョンや設定、
- OS(カーネル)のバージョン
- ディスク容量、空き容量
- 水平/垂直クラスタ環境、HA構成といったシステム構成
- HTTPS接続有無、SAMLなどの認証方式など

#### 3. OS、ミドルウェア(Apache、Tomcat、Oracle)、アプリケーションのログ収集と分析
システムやミドルウェアの設定により、取得できるログに変動がありますが、以下のようなログを取得し、状況を確認、分析します。

※ログを収集する際には、**パフォーマンス問題が発生した期間だけでなく、問題がなかった期間も含め収集する**ようにします。

- OSのログ
  - Windowsサーバーの場合
    - イベントログ(システム、アプリケーション)
    - パフォーマンスログ(定期的にCSV形式で出力している場合)
    ※取得できない場合は、パフォーマンス悪化時のタスクマネージャー、リソースモニターの画像(各タブ全て)などを収集。

  - Linuxサーバーの場合
    - syslog
    - sar
    - vmstat、top(定期的に出力している場合)
    ※取得できない場合は、パフォーマンスが悪化しているタイミングで、vmstat、topを数秒おきに実行した結果を収集。

OSのログの確認方法は、以下の記事も参照ください。

https://qiita.com/tbtakhk/items/de5b682d2334523dafd9

- ミドルウェアのログ
  - Apache
    - アクセスログ(ログフォーマットで、URL、HTTPステータス、リクエスト処理時間、応答が完了した時の接続ステータスなどが出力されている前提)
    - エラーログ

  - Tomcat
    - catalina.out(Windowsの場合、stdoutログ)
    - GCログ(出力設定している場合)
    - アクセスログ(出力設定している場合)

https://qiita.com/tbtakhk/items/5c5a26293e884260dabb

  - Oracle
    - アラートログ
    - リスナーログ
    - Statspackレポート(EE環境の場合は、AWR、ADDM、ASHの各種レポート)

    　Statspackのインストール・設定、レポートの見方については、以下も参照ください。

https://qiita.com/tbtakhk/items/766ee84d051098cc66d4

https://qiita.com/tbtakhk/items/03a100912406c1396c66

- アプリケーションのログ
  - アプリケーションで独自に出力している、パフォーマンス状況が分かるログがあれば、そのログ

※上記に記載したログは、全て必要でない場合もありますが、ログを分析する人と、ログ収集する人が異なる場合など、後からこのログも欲しいといったやり取りが発生すると、状況把握までに無駄な時間がかかってしまいます。その為、パフォーマンス障害調査の際は、どのログを収集すべきか決めておくとよいです。
また、明らかに問題の場所がはっきりしている場合を除き、基本的には、システムを構成する全てのサーバー(サービス)の情報を収集するようにします。

#### 4. ボトルネック箇所の切り分け
3で収集したログを確認し、ボトルネックがどこにありそうか、まずは広い範囲で切り分けしていきます。

OSのパフォーマンスログを確認しつつ、Webサーバー、APサーバー、DBサーバーのどこに問題がありそうか(場合によっては全ての場合もありますが)をまず切り分け、仮にAPサーバーに問題がありそうである場合は、APサーバーのどこに問題がありそうかを深堀りし、ログ等の詳細を確認していきます。

いきなり細かい所から見ていくと、全体でどこがよりパフォーマンスに影響が大きい問題かが見えにくくなるため、必ず広い範囲から確認していくようにします。

各種ログの見方については、別記事にて記載したいと思います。

#### 5. 原因詳細調査とパフォーマンス改善策の検討
4で広い範囲でボトルネックがありそうな箇所を切り分けしたら、その対象について、もう少し詳細に調査します。
複数ある、パフォーマンス悪化要因のうち、最もパフォーマンス改善に効果がありそうなものを見つけ出し、その改善策を検討します。

もし、本番環境に近いデータ量がある、ステージング環境や開発検証環境がある場合は、その環境で改善策を試し、検証してみる事も検討したいですが、時間的猶予などで難しい場合は、この**変更を加える事で改善が見込める根拠を明確に**し、社内およびお客様にレビューを受ける事が大事です。

#### 6. パフォーマンスチューニング改善策の実行と効果測定
改善策について、お客様および社内で承認が得られたら、本番環境に改善策を適用し、効果測定を行います。

※なお、設定等の変更により、万が一動作障害などが発生する場合を想定し、変更前の設定情報等に、すぐに切り戻しできるようにして検証を行うようにします。

改善策により、パフォーマンス状況が、問題発生前の状態に戻ったり、改善が見られた場合は一旦チューニングを完了とします。

効果が見られなかった場合は、一旦チューニング前の状態に戻し、3から再度確認を行い、元の状態に戻るまで対応を繰り返します。

#### 7. 開発へのフィードバック(必要に応じて)
本番環境などで、パフォーマンス問題が発生した場合、根本原因がアプリケーションの実装や設計にある事が分かっても、アプリケーションの修正には時間がかかるため、ミドルウェアの設定変更などによる、暫定対処までになってしまう場合があります。

しかし、問題点がはっきりしたのであれば、再発防止の観点からも、改善要望として製品開発チームにフィードバックする事をお勧めしたいです。

開発にも色々と優先順位があり、また開発に集中していると、本番環境で何が起きているか、意外と知らない(気づけない)場合もあると思います。
少なくとも、わざわざパフォーマンスを悪くしたいと思っている開発者はこの世に存在しないので、より良い製品、サービスにしていくためにも、情報の共有をうまくしていきたい所です。

## おわりに
今回は、パフォーマンスチューニングの目的と流れについて書いてみました。
次回以降、具体的なパフォーマンス調査方法、チューニング方法について記載しようと思います。