ISUCON7参加しました@チームinarisan

ISUCON7の予選に参加しました。

今回参加したチームはチームinarisanです。ギリギリですが本戦出場!!終了1時間前までは諦めが強かったですが、何とか挽回しました。

isucon.net

運営の皆さま、お疲れ様でした。スコアが伸びずに苦労しましたが、その分、学びも多くて問題を解くことを楽しめました。

来月もよろしくお願いします!

チームメンバー

@lukesilviaさん(会社の2年先輩)と@mashanさん(会社の1年先輩)と自分 @sugilog

2015年にもISUCONに同じチームメンバーで参加していて、そのときは予選突破→決勝で撃沈、という感じ。ちなみにそのときのチーム名はチームhammerでした。

今回は、役割をちゃんと意識したり、分担したわけではないですが、ざっと↓の感じに。

@lukesilviaさんが経験豊富なプログラマーなので、全体チェックとDBまわり。

@mashanさんは普段はインフラ管理されているので、OSとかDBとかの設定、nginxでのキャッシュとか、足元の部分を全部。

自分 @sugilogはコードばっかりいじってました。今回用意されたサーバーにログインしたのも10回もないはず。最後はmemcacheと格闘してました。

実装言語

rubyの参考実装から修正をすることにしました。理由はふだん使っているのがrubyだから。

僕個人は最近はGoとNode.jsを扱うほうがおおいのですが、それでも実装スピードはrubyのほうが速くて、チームメンバー3人共あつかえるほうがいいので、やっぱりruby

今回のお題だとそんなに言語に依存してパフォーマンスがブレる、みたいなことも無いんだろうと勝手に思ってますが。。。どうなんでしょ??

コードは恥ずかしいので晒しません。最後にmemcacheと格闘した実装が汚すぎる。

良かったこと

dstatが神:@mashanさんがずっと監視してくれてた。おかげで帯域の詰まりもちゃんと把握できてた。

動作テストをする:@lukesilviaさんがアプリケーションの動作をしっかりチェックしてくれていたので、どこがおかしくなったかに早く気づけた。

最後まで諦めない:勝負に出すぎると最後のスコアを落とすんだけど、ちゃんと積み上げでやったことは裏切らないと思う。

勝負に出るコードはすぐに戻せるようにする:ベンチマークは知らせながら、リバートしたコードを手元に用意しておく。すぐにサーバー側のコードを元に戻せれば傷が浅くて済む。

やったこと

時間軸はだいぶ適当です。記録をちゃんと残してるわけでもないので、だいぶおかしいかも。。。

最初の2時間

  • レギュレーションを読む。
  • コードリーディング。
  • OSとかDBでざっくり変えておいたほうがいい設定を変更。
  • systemctlの切り替え。
  • とりあえずのベンチマーク
  • とりあえずsleepを消す。。。消してよかった?

コード的にはN+1があるから、まずはそこからだね、と言う感じ。

アイコンが確実にボトルネックになりそうなことはわかってたけど、まだ優先順位を決められていない状態。

このときは、ウェブ2台+DB1台の構成を維持。

次の2時間?

  • N+1の解消。
  • アプリから返したアイコンをnginxでキャッシュ。

全然スコアが伸びなくて落ち込む。

次の2時間

帯域が詰まってしまう、ということでその辺を改善。

  • アイコンに対してNginxからキャッシュヘッダーを付けてみる(etag on;とか色々)。
  • ウェブを3台にしてみる。
  • イコン画像の読み込みをlocalhostのDBから読み込むために、DBをレプリケーション構成にする。

ここで5万点くらい?だった気がする。上位チームがうん十万点で争ってたから、がちで凹む。

@lukesilviaさんは予定があるので戦線離脱!!(個人的にはこの時点でプチパニック)

次の1時間

  • アプリケーションからetagヘッダーを付けて返してみる。アイコンの画像名の生成がhexdigestで計算されてたので、とりあえずそれを流用。
  • 部分的にmemcachedからデータを取得できるようにコードを変え始める。
  • ちょっとずつ再起動テストを始める。

あまり伸びず。。。

最後の1時間

  • pumaのスレッドとworkerの数を調整。結局どちらも1か2か、それくらい。
  • memcacheから可能な限りデータを引けるようにする。
  • 再起動テストをしまくる。

他チームのスコアが見えなくなったくらいのタイミングでスコアが急伸。15万点付近まで伸びる。

あれこれやって、途中微妙に鳴ったのでコードを戻して、みたいなことをして、最後の最後で215280(2017-10-22 20:58:58 +0900 JST)。

正直、運が良かった、というところが大きい気がします。