チームRedCompでISUCON6に参加しました

いい感じにスピードアップコンテスト(ISUCON)の第6回にチーム「RedComp」で参加しました!

isucon.net

RedComp

今回は一緒に仕事をしているtakyoshi & mizkeiとチームを組んで参加しました。
Redは赤でCompは粉です。
役割分担は

  • takyoshi : 下回り
  • mizkei : アプリ
  • rg_gs(私) : なんか色々

な感じでした。

やったこと

  1. azure VMs、repo準備
  2. index張る
  3. アプリ、DB統合
  4. htmlify対策
  5. さらばgolang

azure VMs、repo準備

マニュアル記載のテンプレートボタンをぽちっとして競技用のVMを用意。この機能すごい。
が、VMの起動中に焦って計測ツールのインストールやpub key配置用のスクリプトを動かしてしまい、プロビジョニングが中途半端に…
アプリが配置されなかったのでやり直し… 今度は焦らず再起動を待ち、初期状態でベンチ実行。初期はperl実装にベンチがかかり1800点前後。

アプリケーションをrepoに上げ、patchを当て… とこのくらいで大体11:00
アプリ担当のmizkeiはperl < goな人なので言語はgoを選択。
goはマニュアルに記載されていた初期実装ベンチが0点な言語でしたが、とにかくアプリ読んでから考えようということに。

index張る

mizkeiがアプリを読んでいる傍ら、データのバックアップをとったりついでにindexを張ったり。
とはいえDBは非常に小さく、最終的には

alter table entry add index updated_at(updated_at);
alter table star add index keyword(keyword);

くらいだった気がする。
ベンチは //keyword/:keywordタイムアウトしてしまいこの時点でも0〜200点くらい。不穏。

アプリ、DB統合

今回の問題で特徴的だったのはアプリケーションが複数存在し、httpによるデータ交換を行っている点でした。
作りは面白いのですが、特に別アプリになっているメリットがなく(笑)、ひとつのアプリに統合することに。

  • isuda側に /star を移動
  • star tableもisudaのDBに作成
  • nginxの設定からstarの分岐を削除
  • isutarのアプリ停止

等をやりました。
こういった変更はbranchを切って行い、ベンチマークの結果次第でmasterに取り込むかどうかを決める、というルールでやっていたのですが、この時点でもタイムアウトによる減点のためかスコアは0〜200点くらい…
この変更はとりあえず保留に…

htmlify対策

とりあえずスコアが出ないことには効いてるのかどうかもわからん!
ということで一番のボトルネックであるhtmlifyに着手。

  • keywordの長さでsortするクエリ対策のためにcolumnを追加
  • keywordの長さをscoreにしたsorted setを作成し、DBからentryを全取りしないように
  • regexp.MustCompile やばい!となってstrings.Replace

ここまでやってやっと1800点くらい。時刻は16:00くらい。つらい。
普段業務でgoを書けない鬱憤を晴らすかの如く、喜び勇んで手を動かしてたmizkeiもだいぶ意気消沈して来てたw

さらばgolang

結局のところperlの初期実装を超えられておらず、ボトルネックは文字列処理。
じゃあperl使えばいいじゃない
ということでmizkeiがgo書いてる裏でそれを私がperlでも実装。(私はperlのほうが得意)
結構諦め気味で最悪perlの初期実装を提出しようか〜www などと言っていましたが、sorted setからkeywordを取得するようにしたところでスコアが40000点くらいまで伸びISUCON始まった!(でももう17:00)
そこからisutarの統合やらnginxの調整やら大急ぎでやって、最終的には70000点位のスコアは見ることが出来ました。

結果・振り返り

スコア的に期待はしてなかったけどやっぱり結果は予選落ち、残念。
振り返るともっと早い段階でgo捨ててperlにしとけばよかったのでは?となりそうですが、そうでもない。
みんgo第一章にある通りgoの正規表現はパフォーマンスが悪いし、perlはそういうの得意だけど、問題のキモは正規表現の生成速度ではなく、その頻度を減らすことだったり更新後の参照可能性の担保。なので文字列比較やリンクとしての置き換えの回数自体を減らす方向でアプローチしていけばgoでもスコアは出せたんじゃないかなぁと思います。
とは言え初期実装がベンチ0点で、最大のボトルネックを取り去るまで進捗が見えないのはつらかった…

まとめ

今回もとても楽しく参加させていただきました。
問題も今までにない感じで面白かった!(はてなってすごいサービスなんだなぁと思ったり…)

誘ってくれたtakyoshi & mizkeiありがとうございました!
そして運営の皆さん、お疲れ様でした!本選も応援しています。

P.S.
みんなのGo言語買いました!まだちょっとしか読んでませんがとても良さげ。