かみぽわーる

kamipo's blog

ISUCON6予選にチーム「それぞれの椅子」で参加した

ISUCON6予選1日目にチーム「それぞれの椅子(kamipo, Yappo, kan)」で参加した(kanさんは予定があってリモートからの友情出演)。

結果からいうとスコア15万ぐらいで安定したとこでもう時間ないから触るのやめて再起動チェックだけやって終わろうって再起動したら3万ぐらいまでスコア下がって原因特定するには時間なさすぎて死んだ(最後6万ぐらいまでは回復したっぽい)。俺の屍を越えてゆく者へ言えることは、不測の事態にそなえて再起動チェックは時間に余裕をもって何度かやるべきということです。

結果は残念だったけど今回はとても楽しめた。これまでのISUCONではせっかく声をかけて集まってもらったのだからみんなのパフォーマンスを引き出さなければというプレッシャーがハンパなかったけど、みんな大人なんだから自分のパフォーマンスぐらい自分で発揮するやろって気持ちでやれたのがよかった。やっぽさん当日の朝6時ぐらいまで飲んでたけどみそ汁飲んだら復活してたし。

今回のお題ははてなダイアリーを模したキーワードリンクするWebアプリ(+はてなスターとスパム判定が別サービスで立ってるマイクロサービス構成)。キーワードリンクしたHTMLを生成する処理がボトルネックのほぼすべてといっていいお題で、この処理をいかに高速化するか(もしくはオフロードするか)という問題だと理解しました。キーワードリンクは登録されているエントリ名(keyword)の最長マッチが期待されていて、チェッカーは既存のエントリ名をプレフィックスにもつkeywordをPOSTしてきて最長マッチが正しく考慮されているかをチェックしているようでした。

まず我がチームのとった戦略はキーワードマッチのためのregexp生成をRegexp::Assembleを使う&キャッシュすること。これで3万ぐらいまではいったけど、ここからどう速くするかは結構悩んだ。他に多少無駄なところ(高速化の余地)があってもキーワードリンク生成を速くできる目処が立たない限り効果が誤差レベルなので。

このregexp生成のキャッシュ時に確認できたことは、キーワードの最長マッチは常に正確じゃなくてもチェッカーがPOSTしてくる既存のkeywordより長いものが考慮されていれば減点はないということ。そこで最終的には、初期状態からある既存のkeywordに対して置換の前処理(html_escapeの前)をキャッシュすることですべてのページのキーワードリンク処理を高速化し、チェッカーに怒られるkeywordは後で個別に対応するという戦略でキャッシュいれてみたら予想通りスコア上がって15万ぐらいで安定するようになった。残り時間がもう30分を切ってたので個別対応を入れるのは諦めて最後に再起動チェックだけしようって再起動したらスコア3万。原因特定をするにも残り10分切ってたのでenqueueガチャで最後少し回復させるのが限界でフィニッシュ。

再起動チェックする時間が足りなかったのは今後の教訓として、最後まで楽しく取り組めたのは自分の心構え以上に、ボトルネックはわかってるのに高速化する方法が簡単じゃない良い問題だったからだと思う。また、ISUCON5予選と違ってデータベースにボトルネックを寄せていないことは今回学生枠が多いISUCON6にとっても取り組みやすい問題だったのではないかと思います。

とりあえずいつでも飲みにいけます🍺🍶

f:id:kamipo:20160918181234p:plain

入れる時間がなかった人の手による温かみのある個別対応

Comparing master...exclude_keyword · kamipo/isucon6q · GitHub