本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回は面白法人カヤックでWebアプリケーションの運用,インフラを担当している藤原俊一郎さんで,テーマはWebアプリケーションのパフォーマンス改善です。パフォーマンスチューニングとはカヤックではWebアプリケーションはもちろん,ソーシャルゲームもサーバサイドではPerlでの実装を主に行っており,性能的な問題を改善したりトラブルシューティングをしたりすることが多くあります。本稿ではそこで得られた知見を,Webアプリケーションのパフォーマンスチューニング(性能改善)というお題でまとめます。「Webアプリケーションのパフォーマンスチューニング」と言うと,具体的にはどのような作業を想像するでしょうか?「チューニング」=「調整」という語感からか,OSやミドルウェアのパラメータを調整することを思い浮かべる人も多いと思います。チューニングイベントの結果から2011年からWebアプリケーションのチューニングイベントとして,「⁠チューニンガソン⁠」⁠,「⁠ISUCON」というイベントが開催されています。チューニンガソンは,アプリケーションのコードに手を入れることがルール上許されていないため,OSやミドルウェアの設定を主に行うことになります。ISUCONは「なんでもあり」ということで,アプリケーションをどれだけ書き換えても最終的にベンチマーク計測で問題が発見されなければOKというルールでした。この2つのイベントの結果をまとめると,興味深い傾向が見えてきます(表1⁠)⁠。スコアの改善率が10倍以下のチューニンガソン#1~#3と,100倍以上のチューニンガソン#4およびISUCONに二分されます。チューニンガソン#4については上位2チームが飛び抜けたスコア(1,000以上)を残し,3位のスコアは23.95でした。リバースプロキシでのキャッシュ設定が有効に作用したため,スコアが大きく伸びたのだそうです。大きな効果を上げるためにチューニンガソン#1~#3の改善率を見ると,アプリケーションや全体のアーキテクチャに手を入れないで改善できるのは最大でも10倍以下です。数倍速度が違えばサーバ台数を大きく減らせるので有意義なのは間違いないのですが,ISUCONやチューニンガソン#4のような飛躍的な高速化は望めないことがわかります。チューニングでは,単にパラメータ設定を変更するのみではなく,ボトルネックになっているコードやクエリ,アーキテクチャに的確に手を入れていくことで大きな効果を上げることができるのです。ボトルネックの発見と解消が大事システム全体の処理時間についてパレートの法則(経験則)を適用すると,「⁠全体の処理時間の80%は20%の部分で発生している」ということになります。実際にシステム全体で一番ボトルネックになっている部分を解消しないことには,ほかの部分に手を入れても大きな効果を上げることはできません。そのボトルネックはシステムによってまちまちです。データベースの設定であったり,非効率なSQLクエリであったり,行儀の悪いアプリケーションのコードであったり,時間がかかる外部APIの呼び出しだったりします。以降では,そのボトルネックを発見するには具体的にどうすればよいのかを見ていきます。システムの現状を知るパフォーマンスチューニングが必要な場合,何らかの理由で「遅い」と認識しているわけですが,本稿ではサーバサイドのWebアプリケーションに対象を絞りますので,フロントエンド側での問題がないかを簡単に確認しましょう。『ハイパフォーマンスWebサイト』では,次のように書かれています。エンドユーザーの応答時間のうち,HTML文書のダウンロードにかかる時間は10%から20%にすぎない。残りの80%から90%はページ内のすべてのコンポーネントをダウンロードするのに消費される。ChromeのPageSpeed拡張などを利用し,フロントエンド側での問題がないか確認してください。各種メトリクスの収集フロントエンド側ではなく,サーバサイドのWebアプリケーションがレスポンスを返すまでの速度に問題があるという確信が得られたら,まず現状の把握を行います。チューニングを行う場合の鉄則ですが,何を変更し,その結果どのように数値指標が変化したかを計測可能な状態にすることが大事です。計測できない状態でむやみに変更を行うと,改善どころか,かえって性能を落とすことになりかねません。プロダクション環境では普通に行われていることと思いますが,Munin,Cacti,Zabbix,Ganglia,CloudForecastなどのリソースモニタリングツールを利用し,各種の基本的な数値を収集,グラフ化します。Store)などに対する発行クエリ数レスポンスタイムの計測Webアプリケーションへのリクエストに対してレスポンスタイムを計測して可視化することで,次のような現象を把握できます。突発的な現象で,短時間だけレスポンスタイムが悪化した日時が経つにつれて徐々に性能が劣化しているある時点のデプロイ後,障害になるほどではないが性能劣化が認められる死活監視として,特定URLのレスポンスに時間がかかり過ぎた場合に障害と見なすようなことは広く行われているでしょう。それだけでは,一部のリクエストのみ遅くなっていたり,全体の処理速度が徐々に遅くなっていったりする現象を把握できません。チューニングする際の指標となるデータとして,レスポンスタイムを記録し可視化することをお勧めします。nginxの設定例Webサーバがnginxの場合,処理時間として$request_time,$upstream_response_timeをログに記録できます。$request_timeはnginxがリクエストを受け取りはじめてからレスポンスをクライアントに返しきるまでの時間(小数点を含む秒数⁠)⁠,$upstream_response_timeはnginxがリバースプロキシとして動作する場合に,プロキシ先からのレスポンスを得るまでの時間が記録されています。それに加えてリスト1のように$upstream_addrも同時に記録することで,どのアプリケーションサーバに接続して何秒でレスポンスが得られたかをログから読み取ることができます。トラブル時には特定のアプリケーションサーバからのレスポンスのみが悪化するような場合もあるため,同時に記録するとよいでしょう。'"$upstream_addr"';Apacheの設定例WebサーバがApacheの場合,LogFormatの書式に%Dを使用することで処理にかかった時間(マイクロ秒単位)をログに記録できます(リスト2⁠)⁠。combined_timeApacheをリバースプロキシとして動作させた場合には,nginxの$upstream_response_time相当の処理時間を記録する方法がありません。1.234などと出力してログに記録する方法があります(リスト3⁠)⁠。この数値にはWebサーバとアプリケーションサーバの通信にかかった時間が含まれないため,nginxの$upstream_response_timeと完全に等価ではありません。PSGIで動作するアプリケーションでは,Plackに付属するPlack::Middleware::Runtimeを使用することで,簡単にX-Runtimeヘッダを出力できます。combined_runtimeレスポンスタイムの可視化ログファイルに記録しただけでは状態を一目で把握できないため,可視化を行いましょう。多数のホストに記録されたログファイルを収集,マージして解析するのはとても面倒な作業のため,日次で各ホストからscpやrsyncで集約したあとに解析,レポート作成という手段をとることも多いでしょう。そんなときはFluentdを利用すれば,リアルタイムにログを収集し,解析,グラフ化まで行うことができます。アクセスログをパースし,numericcounterでレスポンスタイムの値ごとにグループ化し,GrowthForecast,Zabbixなどのメトリクス収集ツールに送信することで,全体のレスポンスタイムが一目でわかるグラフを作成できます。リスト1の設定でnginxから出力したアクセスログをパースし,$request_timeをZabbixへ送信する例はリスト4のようになります。.*m?s_percentage</match>この例では,ログファイルに記録されたレスポンスタイムを1分ごとに,10ミリ秒未満,10ミリ秒以上~100ミリ秒未満,100ミリ秒以上~500ミリ秒未満,500ミリ秒以上~1秒未満......などとグループ化しています。レスポンスタイムの推移をほぼリアルタイムに(ログが発生してから1分程度の遅れで)把握できるため,運用に非常に役立ちます(図1⁠)⁠。レスポンスタイムの可視化<続きの(2)はこちら。Webアプリケーション著者プロフィール藤原俊一郎(ふじわらしゅんいちろう)2011年より面白法人カヤック。技術部SREチームリーダー。ISUCON優勝3回,出題2回。最近の趣味はマネージドサービスの隙間を埋める隙間家具のようなツールをGoで作ってOSSにすること。著書に『みんなのGo言語[現場で使える実践テクニック]』(共著,技術評論社)。2019」を開催しました。DAY1・DAY2の様子を注目セッションとともにお伝えします。LINEのエンジニア3名がイベントに先駆けて見どころを紹介します。コードの安全性・安定性を高める開発サイクル~テスト管理の効率を上げ,脆弱性診断を自動で行う~本連載では,連載「業務を改善する情報共有の仕掛け」を受けつつ,安全性・安定性を加えた開発サイクルについて考えていきます。若者世代から圧倒的な人気を誇るライブ配信&動画投稿コミュニティアプリ「MixChannel」(ミクチャ)の裏側(レコメンドシステムやサーバサイド開発など)について解説していきます。その他の連載CSS3アニメーションでつくるインターフェイス表現CSS3によるアニメーション表現を紹介していきます。その中でも,幅広い読者に応用してもらえるだろうインターフェイスを主なお題とします。MySQL道普請便り本連載では,MySQLを使ったアプリ開発・運用に関するノウハウをご紹介していきます。RecipeUbuntuの強力なデスクトップ機能を活用するための,いろいろなレシピをお届けします。JavaScriptセキュリティの基礎知識JavaScriptに関するセキュリティ上の問題はどこで発生し,どうすれば防ぐことができるのか?について解説していきます。〜システムをきちんと運用するための基礎知識システムは「作って終わり」ではなく,運用の中でさまざまな問題が発生します。問題の発生に備えて事前にどのような対応をしておくべきなのか,問題発生時に何をしなければならないのか,ポイントを解説していきます。きたみりゅうじの聞かせて珍プレーソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。Linuxのメンテナンスの傍ら,Linuxやオープンソースソフトと日々を過ごす著者が,その魅力とつきあい方を,エッセイ風味でお届けします。PRESS特別編集部員,さわやか笑顔のスーパーハカーはまちちゃんとネット大好き14歳わかばちゃんが,毎号,読者の皆さんから寄せられたおたよりを紹介します。皆さんの日頃の悩みにも答えちゃいますよ。]メールでのお知らせメールで次の案内をお送りしております。メールの配信を希望する方は,利用したい項目をチェックしてメールアドレスを入力し,[登録]ボタンをクリックしてください。UPDATES[ほぼ週間に1回]新刊メールマガジン[ほぼ週間に1回]電脳会議の各号案内[ほぼ1ヵ月半に1回]※変更する場合や停止する場合は,登録情報変更ページをご覧ください。※登録いただいたメールアドレスには,そのお知らせ以外,配信いたしません。Ltd.ページ内容の全部あるいは一部を無断で利用することを禁止します。個別にライセンスが設定されている記事等はそのライセンスに従います。