パフォーマンス面での変化
Webサービスが成長するにつれ、
まずはじめにパフォーマンス改善とは何か、
ブクログのパブー
ブクログのパブー (以下、

電子書籍N年
「電子書籍元年」
サービスが重い
そんな中、
パフォーマンス改善の必要性
ECサイトのパフォーマンス
いちユーザとしての個人的な体験に照らし合わせてみてもわかるとおり、
お客様へのより高い価値を提供するためにも、
継続的な改善
今回は、
そのためには、
パフォーマンス改善の費用対効果
どんなサイトにもいつかは必要になるパフォーマンス改善も、
誰にとっての改善?
パブーには、
- コンテンツを発信する側
- コンテンツを閲覧する側
どちらの側に対しても改善できればそれに越したことはないのですが、
コンテンツ発信側
コンテンツ発信側に対して主に影響するパフォーマンス劣化は、
CGM系サービスの性質上、
コンテンツ閲覧側
CGM系サービスの場合、
また、
現状を把握する
前述のどちら側への対応を行うにせよ、
理解のために対象を分類する
「状況を可視化する」
URLのグルーピング
ここでは、
パブーの場合、
- 読む
(read):電子書籍を読むためのページ群 - 買う
(buy):買うためのページ群 - 探す
(find):探すためのページ群 - 書く
(write):書くためのページ群 - 交流
(communication):作者、 読者の交流のためのページ群 - 書籍
(bookinfo):書籍情報ページ - トップ
(top):トップページ - その他
(others):上記のいずれにも当てはまらないページ群
レスポンスタイムをログに吐く
さて、
Apacheのレスポンスタイムを記録する
Apacheのレスポンスタイムをログに記録するには、
- %D:リクエストを処理するのにかかった時間を、
マイクロ秒単位で記録する - %T:上記と同様の数値を、
秒単位で記録する
ここでは前者の%D
を用いることにしました。
どのURLグループへのアクセスなのかを記録する
また、
// $group に、上記のURLグループのうちのどれかが格納されているapache_note("group", $group);
アクセスされたURLに基づいて、
Apacheのログフォーマット
URLグループとレスポンスタイムをログに記録するための、
LogFormat "time:%t\thost:%h\tmethod:%m\tpath:%U%q\tversion:%H\tstatus:%>s\tsize:%b\treferer:%{Referer}i\tua:%{User-Agent}i\trestime:%D\tgroup:%{group}n" ltsv
ここでは、
レスポンスタイムの%D
については先述のとおりです。URLグループは、group
というキーにひもづくnoteの内容を取り出すための設定%{group}n
を用いて、
Fluentdでログを収集・集約する
Fluentdは、
上述の設定でそれぞれのアプリケーションサーバで記録したログを、
図2 状況可視化システムの構成図

ログ収集用の設定
ログ収集用のFluentdの設定は非常に単純です。
- in_
tailプラグインでApacheのログをパースする - out_
forwardプラグインで集約用Fluentdにログを送信する
具体的にはリスト1のようになります。LTSVに従ったログフォーマットで記録しておけば、
<source>
type tail
path /var/log/httpd/access_log
pos_file /var/log/td-agent/httpd.access_log.pos
tag forward.app.httpd.access
format ltsv
</source>
<match forward.**>
type forward
<server>
host log.example.com
port 24224
</server>
buffer_type file
buffer_path /var/log/td-agent/buffer/forward
</match>
ログ集約用の設定
ログ集約Fluentdのほうは、
- (1) 可視化する必要のないログを無視する
(rewriteプラグイン) - (2) 送信されてきたログを、
URLグループごとに分けて処理する (同上) - (3) マイクロ秒単位の数値を、
ミリ秒単位の数値に変換する (amplifier-filterプラグイン) - (4) URLグループごとに、
平均値、 最小・ 最大値、 パーセンタイル値 [1] を計算する (numeric-monitorプラグイン) - (5) その数値を、
URLグループごとにGrowthForecastに送信し、 グラフ化する (growthforecastプラグイン)
以上を実行するログ集約Fluentdの設定は、
<source>
type forward
port 24224
</source>
<match forward.app.httpd.access>
type rewrite
remove_prefix forward.app.httpd.access
add_prefix filtered
# (1)可視化する必要のないログを無視する
<rule>
key path
pattern ^\/(?:image|css|js|favicon)
ignore true
</rule>
<rule>
key response_time
pattern ^$
ignore true
</rule>
<rule>
key status
pattern ^(?!200)\\d+$
ignore true
</rule>
<rule>
key method
pattern ^(?!GET).+$
ignore true
</rule>
# (2)ログを、URL グループごとに分けて処理する
<rule>
key uriGroup
pattern ^(.+)$
append_to_tag true
fallback other
</rule>
</match>
# (3)マイクロ秒単位の数値を、ミリ秒単位の数値に変換する
<match filtered.**>
type forest
subtype amplifier_filter
remove_prefix flattened
<template>
add_prefix amplified
ratio 1000
key_names response_time
</template>
</match>
# (4)URL グループごとに、平均値、最小・最大値、パーセンタイル値を計算
<match amplified.**>
type forest
subtype numeric_monitor
remove_prefix amplified
<template>
unit minute
tag response_time.__TAG__
aggregate tag
monitor_key response_time
percentiles 90,95
</template>
</match>
# (5)その数値を、URL グループごとにGrowthForecast に送信しグラフ化する
<match response_time.**>
type forest
subtype growthforecast
<template>
gfapi_url http://graph.example.com:5125/api/
service puboo
name_key_pattern .*_(avg|max|min|num|percentile_\d+)
tag_for section
remove_prefix response_time
</template>
</match>
GrowthForecastによる可視化
このようにして収集・


以上のような簡単な実装と設定によって、
さらに定量化を進める
上述した可視化施策により、
グラフによる可視化の不十分な点
グラフによる可視化には、
- ぱっと見ただけでビジュアルに状況がわかる
- 時系列に沿って改善結果を継続的にモニタリングしやすい
というメリットがあります。しかし、
全体の状況をスプレッドシートに落とし込む
そこで、

このシートは次のカラムからなります。
- ① URLグループ
- ② URLグループごとのレスポンスタイムの平均値
- ③ URLグループごとのレスポンスタイムの合計
- ④ URLグループごとのアクセス数
- ⑤ サイト全体のレスポンスタイムの総計に占める③の割合
また、
GitHubのGistにシートを作成するスクリプトを掲載していますので、
優先順位を決定する
この手法の良い点は、
今回このようなシートを作成したことで、
改善戦略への2つのアプローチ
前節までで、
- ボトムアップアプローチ
- トップダウンアプローチ
ボトムアップアプローチ
ボトムアップアプローチとは、
メリット/デメリット
Webサービスを実際に利用しているユーザが感じている問題を解決することは、
ただ、
トップダウンアプローチ
トップダウンアプローチは、
つまり、
メリット/デメリット
このアプローチでは、
とはいえ、
PDCAサイクルをまわす
ボトムアップとトップダウンとでアプローチに違いはあるにせよ、
そのPDCAサイクルにおける改善指標として、
- URLグループごとのグラフ
- 全体状況のスプレッドシート
これらの指標を各々の改善実施前と実施後とで比較することで、
本章のまとめ
推測するな、計測せよ
『サーバ/インフラを支える技術』
本章では、
改善を継続する
重要なのは、
本章がそのための一助となれば幸いです。