ISUCON5予選参加記

チーム「:sushi:食べたい」でISUCON5の予選に参加してきた。 最終スコアは4955点で予選敗退でした。 全体でどのくらいの順位だったのか知りたかったけど公開はされないらしい。 予選突破にはあと3倍弱くらい必要だった。 チームメンバーと共通している言語がなかったのでgolangでやったけどgolang力が足りな過ぎた。

事前にやったこと

bitbucketのwikiに下記の様なことをまとめたりした。

  • 公式サイトやslideへのリンク
  • プロファイリング系ツールのまとめ
    • pprofの使い方
    • qt-query-digestでslow-query-logを集計
    • goaccessでnginxのログを集計
  • チューニング系のまとめ
    • 速度チューニングしたmy.cnf
    • limits.conf, sysctl.confなどの秘伝のタレ
    • golangunix domain socketでいろいろ繋ぐコード
  • チームメンバーの公開鍵
  • 運営からの連絡
  • 当日の時間配分

isucon4の予選をやりながらまとめたのでubuntu寄りの情報になっていなくて本番はスロースタートになってしまったのが残念だった。 ubuntuが来ることは公開されていたのでもう少しubuntuで簡単に展開できるようにしておけばよかった。 当日の情報もwikiに追記していけば良かったので最低限ページを用意していたのは良かった。

当日やったこと

土曜日に参加したので11:00からスタートだった。LINEカフェで参加していて1時間くらい空き時間があったので、まとめ切れていなかったlimits.confのメモリ周りの記事を見たり、tagomorisさんとkamipoさんのインタビュー記事を読んでどんな問題が出るかみたいな話をしていた気がする。

序盤

とりあえず、初期状態でベンチを回してスコアが200くらいだった。

役割分担的には自分がプロファイル系ツールを用意して、ほかの二人がアプリの中身を読んだり、サーバーを用意したりしてもらった。

ソースコードと設定ファイルはプライベートリポジトリで管理しながらすすめて、割と並列で動けるようになっていた。

ubuntu 15.04力が低すぎてsystemdとかapparomorとか全然わからなかったけどインフラ得意なメンバーが全部やってくれて圧倒的感謝しかなかった。

ベンチマーク動かしつつ、色々設定ファイル変えながらメトリクスのインストールスクリプト整えるのに1時間半くらいかかってしまっていたのでここはもう少し準備しておくべきだった。このあたりで加えた変更はnginxのプロセス数を増やしたり、mysqlにインデックス張ったりした。isucon4予選でしか練習してなかったのでschema.sqlにインデックス張れば反映されると勘違いしていたので実はこの時点張ったと思っていたインデックスは貼れていなかった。しかも後で見てみるとチャットにメンバーがヒントになりそうなこと書いていたりしたので自分もう少し早く気づけという感じだった。この時点でたしかスコアは700くらいだったと思う。

中盤

/とかrelationsとかが重いということが集計からわかっていたのでそのあたりを潰すためにsqlを書き換えたりしていた。one/anotherを片方だけにする派とinsert減らす派がいたっぽいけど後者だった。insertほとんどないので前者の方が早くなっていた感ある。

この後もひたすら重いと出ていたentriesとcommentsのjoinやentriesを1000件とってきているところをうまく書き換えられないかとやっていたけどsql力が低くてうまくいかなかった。sql書き換えている途中でalterじゃないとだめだと気付いたので適用してスコア1200くらいになっていた。

終盤

中盤からメンバーにやってもらっていたusers周りのキャッシュのベンチが通ったのでマージしようとするも変更が割とあって恐怖だったので一番効くらしいrelationsのキャッシュだけ拝借することにした。この変更が割と効いてスコアが4200くらいになった。

残り時間が少なくなってきたのでやればスコア上がる系のmysqlにsocketで繋ぐなどの変更を加えたところ、my.cnfが反映されていないという疑惑が出てきた。確かにmy.cnfに書いてあるsocketの位置と実際に作成されているsocketの位置が異なっていたが、slow-query-logの設定などは反映されていたのでおそらく別の設定ファイルで上書きされていたとかだろうか(時間もなかったので調べられていない)。my.cnfを一か所にまとめたところ今度はmysqlが起動しなくなってこの時点で終了30分前とかだったので、これはやばいと切り戻して、アプリの方を書き換えてsocketで繋ぐようにした。

終了1時間でやることは事前に決めていたのでメトリクス系ツールやログの出力をoffにしたり、再起動してちゃんと動くかなどを確認した。10分前で最後のベンチ回すか、といって回したところ数回に一回出るタマキのエラーに襲われて、これまたやばいとなったけどすぐに回し直したら正常に終了し、正の得点で終えることができた。ログを切った効果で若干スコアが上がり最終の4955となった。

まとめ

isucon4予選とは真逆な感じのアプリでいろいろ入り組んでいて面白かった。 基本的に地力がが足りていない感じだったので、来年までに鍛えておきたい。