ISUCON7 に参加して相変わらず予選敗退しました。
相変わらず予選落ちしたのですが来年も ISUCON あるならきっと出場するので一年後の自分に向けて記録を残します。
事前にやったこと
ISUCON6 の予選を一度振り返って Nginx の設定や Perl のインストール方法を確認しました。
今回のお題: チャットアプリ
今回のお題は WEB2 + DB1 の構成のチャットアプリでした。
最初に SSH でログインしてよく使うコマンドをインストールしました。で cat /proc/version
, cat /proc/cpuinfo
, cat /proc/meminfo
を実行したらどのサーバーもそんなに性能高くない。前回のようにアプリケーション側がボトルネックになるのかな、と思いました。
で、最初は WEB1 + DB1 でベンチまわしながら改修してやる事がなくなったら WEB2 + DB1 にしてベンチを回す事にしました。
使用言語: Perl
チャットツールなので Node.js にしようか迷ったんですが、まあ改善していてそっちがいいなら後で乗り換える事にして使用言語を Perl にしました。
Perl にして自前のProfiler を使ってボトルネックを探す。GET /icons/:file_name
と GET /fetch
に問題があることがわかったのでここから着手。
$VAR1 = { 'Isubata::Web => GET /add_channel' => '0.000207901000976562', 'Isubata::Web => GET /profile/:user_name' => '0.0258147716522217', 'Isubata::Web => POST /login' => '0.0591163635253906', 'Isubata::Web => GET /message' => '0.823127031326294', 'Isubata::Web => POST /profile' => '0.0322229862213135', 'Isubata::Web => GET /icons/:file_name' => '42.7363834381104', 'Isubata::Web => POST /register' => '0.0101079940795898', 'Isubata::Web => GET /channel/{channel_id:[0-9]+}' => '0.0515058040618896', 'Isubata::Web => GET /fetch' => '20.0142226219177', 'Isubata::Web => POST /message' => '0.0495190620422363' };
top -c
で WEB と DB を見てたら DB が悲鳴を上げている。コードを見たら画像データが DB に入っている。普通に考えたら Nginx に静的ファイルとして返すようにさせるべきなのですがとりあえず手っ取り早く WEB 側に Redis を入れることにしました。
これで 9000 点ぐらい。
fetch に関しては Index を貼るだけ。ちなみに sleep(1) という関数があったのでよくわからずコメントアウトしてしまいました。これは後々意味を持つ関数だったようです。私はそこまでたどり着けませんでしたが...
これで 20000 点ぐらい。
ベンチが静的ファイルを返すのが遅いというので Nginx が返すように設定すると今度は GET /icons/:file_name
がタイムアウトするというメッセージ
なんだけどマシーンのリソースはまだ限界じゃない。どうしたらいいんだろう...と停滞。
304 ではないだろうか?
ベンチを回しながらブラウザで GET /icons/:file_name
を連打してみたら確かに遅い。なんだけど違和感。ブラウザがキャッシュしていない。
そうだ304だ。ベンチマークが Requset ヘッダーに 'if-modified-since' をつけるんじゃないかと思い、ネットで検索した適当な日付を入れてみた。
$c->res->header('Last-Modified','Sat,22 Feb 2015 12:01:19 GMT');
ただし、これではベンチマークが if-modified-since
を送ってくれなかった。ブラウザでアクセスすると送ってくれるのですが...という事で 304 で対処できないと思いこむ。
競技終了後で他の人の話しを聞いてところどうやら response の時に Date
と Last-Modified
の整合性がとれてないと if-modified-since
を送っていないのかも。後日要検証。
そんなこんなで 304 で対処する以外に道があるのか!?いや、なくない?いや、きっとある!みたいなせめぎ合いを一人で始めて急にネットで画像配信の記事を読んだりして他に方法がないのか模索開始してそのまま迷宮入り。
あとは WEB2 + DB1 の構成にしてベンチをとって 30000点 ぐらい。拡張子の処理を正規表現で書き換えたりして少し早くしようとしましたが焼け石に水。
そして競技終了。
感想
普段リクエストヘッダーの事までは意識しないので今回のお題は大変勉強になりました。競技用のサーバー構築に非常に苦労されたようで、運営の皆様は大変お疲れ様でした。
来年も ISUCON 開催されたら、また挑戦させて頂きたいので何卒よろしくお願い致します。