ISUCON6予選に学生枠で参加して予選通過した

予選通過した!!!!!!めっちゃ嬉しい!!!!!!

isucon.net

結果

チーム名: チーム卒業

学生枠4位 42979点

メンバーと役割分担

  • @pg_mot : インフラ周り
  • @ABCanG1015 : ミドルウェアとアプリ
  • @syusui_s : アプリ

役割分担と書きましたが,実際には高度の柔軟性を維持しつつ臨機応変に役割が変動していった感じです.

準備

チーム結成後はslackチームを作り,githubsshキーとかリポジトリを作成して共有したりしました. あとは, HackMD - Collaborative markdown notes Hackmdっていうマークダウンで書けるGoogle Docsみたいなやつを使って資料やログ,作業ログの共有をしました.

参加前に何度か練習をしておきたいと思って, ansible-isucon/isucon5-qualifier at master · matsuu/ansible-isucon · GitHub こちらのイメージを無料課金枠で置いておいて各自好きなように変えようみたいな仕組みにしました.

本当は8時間とってやりたかったけど,時間がなくて個人練習を個別にやっておこうみたいな雑なノリで当日を迎えました.

当日の流れ

開始前

まず,始まる前に作戦会議をして,最初にやることリストを挙げたりしました. 具体的には,ssh-keyの登録だの,ベンチとりあえず回すなど先人の知識を元にホワイトボードに書き出して役割分担しました.

開始後

とりあえずazure deployしてその間にレギュレーションやマニュアルの読みあわせを行いました. deploy後はソースを全員で読んで挙動確認をしたりしながら,ベンチマーク回し始めました.

ちなみに今回はRubyを選択しています.

詳しい課題内容はそのうち公開されるので詳しくは書きませんが,要するにはてなキーワード自動リンク + はてなスターを高速化するという感じです. この自動リンクは非常に面倒で,初期実装では存在するキーワードを全部「|」パーティクルバーでつなげて正規表現をかけて,該当したワードのところをaタグに置き換え直すという処理が行われていました.この実装だと,キーワードの数に比例して計算量が増えていく上,ページレンダリングの際に毎回処理していたりすると大変なことになるのがわかります.

この時点で,プロファイラなどを取ったところ80〜90%が使われていた上,他にボトルネックになっていそうなところがパッと見でわからなかったので,何らかのアルゴリズム置き換えが必要だと考えました.キャッシュ戦略も取れるかなと思ったのですが,キーワード追加の際には結局再度キャッシュ生成が必要なので,対して効果がなさそうと判断しました.

とりあえず「はてなキーワード 実装 高速化」などで調べると, エイホ–コラシック法 - Wikipedia このようなアルゴリズムについての説明が出てきました.

当初はこの実装は間に合わない可能性が高く,手を付けない方針でしたが,逆にそれ以外のボトルネックを見つけるのが難しかったのと,syusuiくんのruby力を見込んでお願いしたところやる気になってくれたのもあり,AC法の実装を決断しました.

並行して,僕とabcangくんは他のボトルネック探しと,解消をはじめました.

ベンチマークを何度か回しているうちに,自動リンク機能以外のところでタイムアウトが大量発生していることに気づきました. 最初はnginxやsysctlのパラメータなどを先人のタレを使い設定してみたりしましたが,どうも解消せず少し時間を食ってしまいました.

昼を過ぎ間もなく時間も折り返しという時刻近くになり,はてなスターの処理がどうもミスを繰り返していることに気づいたので実装を見返すと,はてなキーワードはてなスター間のスター情報のやり取りにHTTPが利用されている!ことに思い出し(microserviceみたいになってた),冷静に考えると,「ベンチマークがHTTPでめっちゃやってくる」→「スター情報のやり取りで自分にHTTP投げる」→「ソケットやら負荷やらが集中しスター情報のやり取り及びベンチマークのHTTPが処理できなくなる」→「結果的にベンチマークタイムアウトが発生する」という流れになっていることがわかりました.

ここで,はてなスターの処理をすべてはてなキーワード側に移植したところ,1000点以下ではありましたが,点数が出始めました. 今になって思えば,ここは正直もう少し早めにやっておくべきだったかなと思います.当時は自動リンク機能が重いからそれ直さないと時間かける意味があるのかわからないというあたりで放置していました.

タイムアウト問題が大方直ってきたあたりで,abcangくんには自動リンク機能のリンク作成時に利用するkeywordリストを生成するSQLが重い問題についてredisを利用しての解決に着手してもらい始めました.僕はこの間に他の問題点を探して細かく潰したり,時間管理をしつつ二人をフォローする形に回ることとなりました.

そうこうしているうちに,syusuiくんによるAC法実装が完成しアプリに組み込む流れとなりました.アプリに組み込みベンチマークを回すと,1万点ほどまで点数があがりました. またすぐに,abcangくんのredis実装周りが終了し互いを組み合わせると一気に3万か4万点まで上昇しました.参加は2日目だったのですが,リーダーボードに我々のチーム名が乗っていたのは非常に感動しました.

f:id:programmerMOT:20160919153514p:plain

他にも施策としてstatic fileをnginxから配ったり,select *をやめたりと細かいことをしました.

その後,再起動後に正常に動くかという検証・修正や,AC法を中心とした全体の細かいエラー潰しを行い無事今回の点数が出ました. 最後の方は時間がぎりぎりになり終了10分前にようやくPCから手を離すというかなりギリギリのラインを攻めてだいぶ疲れました.

まとめ

良かった点

  • syusuiくんがAC法実装しっかりやってくれたので助かった
  • abcangくんがredisとかの実装しっかりやってくれたので助かった
  • 自動リンク機能から逃げなくてよかった(逃げなかったsyusui君偉い)

良くなかった点

  • starの処理統合をもっと早い段階ですればよかった
  • 自動リンク機能以外のボトルネック探しが遅かった
  • 最後の方もう,いてまえいてまえの精神でガンガン設定変えたりしてしまった(結果論的によかったけど本番は気をつける)
  • isupamについて何もしなかったのはアレでよかったのかな?

感想

勉強になればそれでいいか〜ノリで行くぞみたいな気持ちであんまり練習できてなかったにも関わらず学生枠という形で本戦参加できたのはすごい嬉しいです. 本番でも自分たちの全力を出せるように腰を入れて練習していきたいと思いました.

また今回の予選を準備し提供してくださった運営の皆様,大変お疲れ様でした.本戦でもよろしくお願いいたします.

関連ポスト

チームメンバーのABCanG1015くんの記事 abcang.hatenablog.com

ここにsyusui_sくんの記事リンクが貼られます.