環境構築は普通に出来て、負荷分散でちょっとした台数動いている程度、サーバの能力をある程度食い切ってる程度のプロジェクトが対象です。
処方箋スタート!
1.まずはモニタリング(工数:〜半日程度)
ここでいうモニタリングは死活監視ではなく、主に性能監視、それもアプリケーションの。プロジェクトのレベルがイマイチな状態で、ボトルネックを可視化し対策していく事は困難です。なのでコレはお金の力で解決してしまいます。
NewRelic
http://newrelic.com/
詳細解説は他の記事に譲るとして、使う上での個人的なポイント
- ロードバランサ配下の1台にだけ入れる(費用節約)
- よく見るのはMONITORINGのTransactionsとDatabasesのtrace(なので有償版が必要)
- Errorsも結構役に立つ
平たく言うと、遅くて回数の多い処理のtraceを見て、そこに対してチューニングしていきます。slow log自体はミドルウェアやフレームワークで出力出来たりもしますが、炎上するプロジェクトにおいて、これらがNewRelicと同等レベルに見やすい状態になっている事は無いでしょう。有償版は結構高いですが、エンジニアの迷走工数の方がはるかに高いので、サクッといきましょう。
2. 静的ファイルをCDNに逃がす(工数:1時間〜)
LAMPのベーシックな構成だとmod_phpを使う事が多いと思いますが、この場合、静的ファイルとアプリケーション処理が同列のプロセスでの処理になってしまいがちです。なので、負荷が高くなった際の挙動がピーキーになりがちです。
CDN自体は色々ありますが、有名どころで敷居が低いものだとCloudFrontでしょうか。世の中の記事だと、S3とセットになっているものが多いのでS3が必須っぽく感じるかもしれませんが、オンプレでAWSとは関係ないデータセンターでも利用可能です。
- サービス用FQDNに対してCloudFrontを設定する
- Viewを編集して、移して良いファイルだけCloudFrontのFQDNに参照を向ける
という流れだと、リスクは小さく、CDNへの移転を進められます。
また、CDNに不慣れな場合はファイルが書き換わらないという問題が出ると思うので、その場合、オブジェクトのヘッダを無視したCustomizeなTTLを当てても良いかもしれません。
3. MySQLのチューニング(工数:〜1週間程度)
こちらも遅いクエリとして見つかったものに対し、対処をしていく形になります。
- 参照系であれば、クエリキャッシュやキャッシュ機構でまずは代替可能か。代替不能な場合、適切にインデックスを使用しているか
- 更新系であれば、不用意なテーブルロックが発生していないか。その他、不要なインデックスが無いか。
あたりでしょうか。
特に、DBAやそれに相当するスキルの人がいないプロジェクトでは、各カラムにインデックスを張りまくったりという事件もありますのでご注意を。
インデックスに纏わる注意点
- InnoDBの場合、クエリーで使用できるインデックスは、原則、各テーブルにつき1つだけなので、カラム毎に乱発したインデックスはまともに使われないので、複合インデックスにした方が良い
- 最近のMySQLバージョンだとインデックスマージが結構機能するので、乱発という程でないインデックスはそれなりに活用される(基本的には複合インデックスの方が速い)
- インデックスは複合インデックスの場合も含め、カーディナリティが高い(簡単に言うと、一撃でグッと絞り込める)ところに張ります。なので、レコード有効フラグ的なところに張るのは基本的に効果が低いです。
4. PHPのチューニング(工数:数時間〜)
遅いTransactionsとして見つかったものに対し、処理ロジックを改善していきます。見つかった後のコレは普通の話なので省略します。
あとがき
費用対効果が高めで、出来ていなそうなポイントを並べています。なので、リリース前のチェックシートとして使うのは推奨しません。
参考になりそうな記事
詳解 NewRelic で監視&性能改善〜その1
http://qiita.com/wapa5pow/items/e3ef018af270cc2ad014
AWS CloudFrontで極力キャッシュさせたくない時の話
http://qiita.com/shogomuranushi/items/a2367350ea54a8f41257
MySQLクエリパフォーマンス改善簡易まとめ
http://qiita.com/pekimoche/items/6a5d771d41168e9b738d
カーディナリティについてまとめてみた
http://qiita.com/soyanchu/items/034be19a2e3cb87b2efb