鳩舎

レースしない

ISUCON5 で準優勝しました

今年も @mirakui@sora_h と一緒に ISUCON5 に出場して、準優勝しました。

やったこと

時間は投入した時間。

  • 12:00 : API リクエストを送る先の services が DB に入ってるけど大した数でもない(7つ)ので、全部アプリケーションにハードコードした。
    • これはのちにリクエストにプロキシを挟む時にコード変更だけでよくなったので地味に効いた。なお、これによる高速化はあんまりしなかった(そりゃそうだ)。
  • 13:16 : API リクエストへのパラメータを保存している subscriptions の保管先を DB から Redis へ変更。
    • DB 問い合わせへの高速化というより、 JSON 形式から MessagePack 形式での保存になったことの方が重要な気がしてる
    • ま、これも大した効果は出てない。
    • initialize でバグったら話にならないから、それを回避するように気を使った
    • これはのちに API レスポンスを Redis でのキャッシュする際にすでに Redis への接続と Redis の initialize の準備が終わっていた。という点で効果を発揮することになる。
  • 14:21 : API リクエストの結果を Redis へキャッシュするように
    • 一部、キャッシュ期限がながいと問題を起こすので Expires は後に修正される。
    • Last-Modified にここで気づけていればといまだ悔やんでいる。ちくしょう。くやしい。
  • この後、API リクエストへの並列化などを sorah がやるのだが、どうしても Too Many Request が起こり続けるのでリクエストの交通整理をする Proxy が必要だという話になる。そのまま二人がこっちをむいて『え、出来ないの?』みたいなツラをするので『できらぁ!』と touch proxy.go して開発開始。
  • 16:36 : API Proxy の初版完成
    • 接続先を自由に変えられるように準備をしておいた
    • mirakui の手間を減らすため、 Makefile で依存パッケージやビルドをうまいことできるようにしておく。
      • 地味に make build をちゃんと作っておくというのは効果が出る。
      • インフラエンジニアに優しいコードを書こう
    • 高速に稼働するかどうかは大体自信があったし、俺の Proxy よりその先の API の方が絶対遅いから俺の Proxy はボトルネックにならねぇ!と自分に言い聞かせた。
    • なお、 GOMAXPROCS を入れ忘れたことに後で気付いて慌てて直す模様。
  • 17:15 : まだ TMR が出る。条件を調べるのは俺はやってなくて、 Go のコード見なおしたりしてたんだけど、どうやら Token が同じものを同時にリクエスト送るとダメらしい。その辺どうしようかという話になったので Proxy 側で吸収するから安心しろと声をかけると sorah が『ヤッター!』と声に出して喜んだのがかわいかった。
  • 17:37 : ということで約束を守るべく上記条件を守る仕様を 20 分ちょいで実装。バグなく投入できてお父さん安心しました。
    • この辺でもう疲れきって頭ほとんど動いてない。
    • 『多分行けると思うけど、俺もう mutex は手癖で書いてるからよく考えてない』と mirakui にはこぼしたのだが、実際、 ISUCON4 の時に『俺は並列処理が死ぬほど苦手なんだよ!』と運営部屋で泣き言漏らしてからはちゃんと勉強したし、それこそ手癖で Mutex 周りを書ける程度にはなっていてよかった。
    • なお、綺麗にバグなく投入できた模様。
  • 17:50 : 手元で行う最終計測。再起動試験はふたりにまかせていたのでこの辺では俺は Proxy のコードを読みなおしながら『Mutex ちゃんと動いていてかわいいなあ』とか思ってた。

いいインフラエンジニアが二人いるとコードを書くだけの機械になれて最高

二人は config の変更や小さいパッチが多いので直接 master にコミットしているのだが、俺のパッチは大抵の場合でかい(上を見てもらえれば分かる通り)ので、概ね PR にして出している。 GitHub 上で revert 出来るようにするためで、こういう焦っている状況で自分が git のコマンドを間違えないなんてことはまずないだろうという自分への不信から、そうやってる。

おかげでコードレビューをする機会があるので、二人が詳しくなにをやってたか俺はわかってないけど二人は大体俺が何やってたか知ってる状況にある。これはいいことで、書かれたアプリケーションの内部をわかってるインフラエンジニアは、うまくリソースを使うために適切なインスタンスにアプリケーションを配置してくれる。いやー、こうして書いてみると俺ほんとに二人に依存してるだけだな。無能かよ。

ただまぁ、今回自分のパッチを revert するようなことになることはなかった、というか、基本『あ、やっぱさっきのなしで!』と手戻りすることがなかったと思う。この辺の『妥当なことを妥当にやり続ける』というのが出来るようになったのは明らかに出題してからなので、みんな ISUCON で勝ちたかったら ISUCON の出題者やる方がいい。特にベンチマーカー実装者は Mutex を無意識で書けるようになるぞ!

HTTP/2 について

多分 h2 だったと思うんだけど、何で書かれてるかわかってない。3つか4つ、 Go のライブラリを試したのだが、古いのもあたらしいのも動かなかったので途中で諦めた。

libcurl + nghttp2 だと動いた、 node-http2 がいけるみたいな話なので、 h2 説が濃厚かな。 h2 に対応してる h2-12 に対応してる Jxck さんの http2 でもダメだったから、やっぱ h2 だと思う。

他、いろいろ試そうと奮闘していたのだが途中で手元から API サーバーに繋がらなくなって諦めた。どうやら俺のおかげで何度か API サーバーが死んでいたらしいとあとで聞かされたが、しったことか思わせぶりなことする奴が悪い(冗談です、ごめんなさい)。

まとめ

Proxy を書いていた1時間のうち 30 分程度は HTTP/2 のライブラリをいろいろ試すのに時間を食われていて非常に悔しい。一個試してダメだった瞬間にもう考えるの辞めればよかった。思わせぶりな女子に貢ぐみたいな感じになっていた。

また、俺がやっていたこと以外は 昼メシ物語 とか読むといい。 mirakui はよく働くしいいリーダーやでほんま。お前らにはやらん。

sora_h と今年は喧嘩してないって mirakui が書いてたけど本当で、 mirakui が俺と sora_h の『喧嘩』と『言い合い』の違いがわかるようになったの、あきらかに ISUCON4 の準備中なのでやっぱり出題しといてよかったな!

で、寝坊してタクシー飛び乗ったんですけど、寝不足の頭で役に立たないくらいなら寝坊しても寝たほうがいいと思います(結果がマシだったから言えること)。

ということで、お疲れ様でした。出題チームには感謝しかない。嘘です。悔しいです。悔しい。悔しい。クソッ。来年は優勝したさすぎる……。

あわせて読みたい