- 2016/9/24 土曜日 18:14:08
- ISUCON
去年は初めて予選敗退し悔しい思いをしたISUCONに今年も山形組として参加してきました。
結果は総合二位で本戦出場を決めました。やった!
事前準備
前日にメンバーで作戦会議をして、「フルスクラッチ書き換えはやらない」という方針で大決定。過去フルスクラッチ書き換えでそこそこの結果を残してきた我がチームですが、去年の予選で手痛い失敗をしたのもあり今年は確実に予選を突破しようということで封印することになりました。
過去問を改めて解いたりはしなかったですが、matsuuさんのazure-isucon-templatesの一つをazureにdeployしてみて、なるほどazureはこういう感じかというのを確認したりはしていました。
当日
10:00
はじまっておもむろにazureにdeployしたところ
テンプレート デプロイ 'Microsoft.Template' は、検証プロシージャによって無効と判断されました。追跡 ID は 'a080b1d6-56fc-47d7-9228-9de96209bd0e' です。詳細については、内部エラーを参照してください。使用方法の詳細については、https://aka.ms/arm-deploy を参照してください。 (コード: InvalidTemplateDeployment)
というエラーがでてしばらく苦しめられる。もしやとおもい検証用にdeployしていた過去問のリソースを削除したら解消。
ISUCON、無料枠の制限とかはまるの嫌なので速攻課金解放した
— fujiwara (@fujiwara) September 11, 2016
fujiwaraさんのこのtweetはもちろん見ていたので、事前に従量課金サブスクリプションを作っていたんですが、今確認したら従量課金なのに無料試用プランであることには変わりがないようで、これどうやって解放するのかわからん。さようならazureという気分です。
deploy完了後、初期状態でPerlで動いていることを確認し、そのまま行くことに。
その後1時間ほどは
- 初回ベンチ実行
- コードのローカルへの転送とgitへの展開
- nginxアクセスログを解析用に修正
- カーネルパラメーターやapt-get, cpanfileの秘伝のタレの投入
- コードの解読
- プロファイリングするまでもない明らかにボトルネックになるポイントをさくっと修正
などをやる。プロファイリングするまでもない明らかにボトルネックになるポイントの修正は具体的には
- ON DUPLICATE KEY UPDATEの無駄なデータの二重転送排除
- author_id = ?, keyword = ?, description = ?, updated_at = NOW() - ], ($user_id, $keyword, $description) x 2); + author_id = VALUES(author_id), keyword = VALUES(keyword), description = VALUES(description), updated_at = NOW() + ], $user_id, $keyword, $description);
- is_spam_contentsをtitle/bodyでひとまとめに
- isupam, isutarへの接続をkeepalive
といったあたり。このへんをやって11:30ごろ5262点で暫定2位の状態で最初の作戦会議の開催。
11:30
スコア: 5262
第一回作戦会議。アクセスログの解析はできていて、静的ファイル配信とトップがとにかく遅いというのを確認。
- cssのnginx serve
- isutarをisudaに吸収
- gzip_static
をまずはやりましょうとなる。キーワードリンク作成のhtmlifyが本丸でしょうという話はしたけどこの時点でこれについての具体的な解決策はなし。
12:07
isutarのisudaへの吸収完了。
スコア: 5262->5392
が、スコア上昇は誤差の範囲。既にkeepaliveはしていたのでこの時点では意味のない施策だったんだと思われ。ただし状況が進んでハイトラフィックな状態になると効いてくると思うので問題なし。
12:09
isudaのworker数を20にしてみるとスコアが倍増
スコア: 5392->11090
12:14
static fileのnginx serve
スコア: 11090->10902
うーん、誤差の範囲。
このあとmysqlのindex作成など細かい施策をしばらく繰り返すがたいしたスコア上昇には繋がらなくなってきたため、本丸のhtmlifyの改修に着手。
14:04
スコア: 11090->25048
トップページ表示のときに正規表現の作成がエントリごとに行われていたのを1回に集約
16:17
正規表現とキーワードリストをmemcachedにキャッシュ
スコア: 25048->61473
htmlifyの最適化は2時間以上ずーっと取り組んで着実にスコアはあがっていったしずっとボードの5-6位以内につけてたけどこのころすでに20万点オーバーのチームが現れており、このままじゃ駄目だ…と焦りはじめる。
なにか違うアプローチでブレークスルーをおこさないと勝てない、ということでhtmlごとキャッシュの戦略を実施する方向に転換。
16:59
PlackのsessionをPlack::Middleware::Session::Simpleに置き換え。
Plack::Middleware::Session::Simple なにがすごいかというと、必要の無い時にSet-Cookieしないところです
— Masahiro Nagano / 長野雅広 (@kazeburo) September 18, 2016
logoutの処理を
- $c->env->{'psgix.session'} = {}; + $c->env->{'psgix.session.options'} = {expire => 1};
にしないとセッションがちゃんと切れずにベンチがfailするのにしばらくはまるが解消。
スコア: 61473->67663
キャッシュするための準備でしかないが、スコアがあがり期待が高まる。
17:03
nginxで$cookie_isuda_sessionがない時だけ
proxy_cache_valid 200 1;
をするようにする。
スコア: 67663->228217
きたー。
で、しばらくもうちょっとスコアあげられないか試したけど誤差の範囲でしか変わりがなかったので17:30ごろにはあとは再起動検証をして終わりにしましょう、となり再起動…
17:38
再起動後1回目
スコア: 18万点台(正確なのはとっておらず)
ん、ちょっとおちたなぁ、mysqlのウォームアップ的なあれだろうか、ともう一度実行することに。
スコア: 30435
え?なんで?何がおきたの?
まったく原因もわからず混乱する一同。そして祈りながらもう一度ベンチマーク実行するも、また数万点台のスコアを叩き出す。
残り時間15分。終わった。俺たちの夏は終わってしまったんやー。
と、泣きそうになりながらもう一度再起動をしてみる…。
17:50
再起動2回目
スコア: 19万点台(正確なのはとっておらず)
よし!なんでかわかんないけど命拾いした!ベストスコアからはおちてるけどこれは予選突破できる数値でしょう。
もうやめよう…と思ったけど、「もう一度走らせてみましょう」というチームメンバー。まじか。止める間もなくエンキューされる。
スコア: 223103 (17:54:14)
なんとその日のベストスコアを更新。そのままフィニッシュ。
感想
最後のはなんだったのかいまだに分からず。終了後にidobataで疑問を呈したりもしたのですが、1秒間のキャッシュというきわどい戦略だったので減点によるブレが大きかったのではないかという推察で終わっています。
エンキューガチャ的なことはなかったと信じたいけど、ちょっとだけもやっとしているので、ベンチの再現環境が提供されたら、いろいろと試してみたいです。
うちがhtmlごと1秒キャッシュというきわどい戦略だったのに対し、他の通過者の感想エントリーを見て回るとhtmlifyの最適化やプリレンダとその効率的なinvalidationなど自分にはできてないことがたくさんあって勉強になるし、これらをちゃんとできるようにならないと本戦は無理だろうなという感じで、2位通過なのにだいぶ厳しい気持ちになっております。
何はともあれ、再びヒカリエでの本戦に参加できることは本当に本当にうれしいです。
songmuさんをはじめ出題者のみなさん、運営者のみなさん、お疲れ様でした。本戦もよろしくお願いいたします。
今度こそ優勝するぞ!
コメント:0
トラックバック:0
- この記事のトラックバック URL
- https://blog.everqueue.com/chiba/2016/09/24/741/trackback/
- トラックバックの送信元リスト
- #isucon 6 予選二位で通過しました - へぼい日記 より